Grasshopper Python 104
Lists
In the last post we discussed applying conditional operations to single values. But that is way too simple. We expect to process many different values when working with Grasshopper and the power of scripting increases when we deal with collections of data. The main collection type you should care about is The List.
Working With Lists
Lists can be created or processed within the scope of a Grasshopper Python scripting component. To access an input parameter as a list we must specify so in the context menu. This will allow us to iterate through all the elements of the list instead of performing the defined operations for each input by default, as happened in the examples in 103.
Now we can access the list as a whole to, for instance, measure how many elements are there in the list with the Count property.
a = "There are %d elements in the list" %(len(x)) # Here we are also using a variable placeholder.
Declaring Lists
In order to process a list we are going to need a bit more of flow control than just conditionals but before diving into loops let’s see how to declare and populate a list inside a Python component.
List declaration works like other variables but you need to supply values inside square brackets and separated by commas.
myList = [1,2,4,9,16,25] # Lists are declared by providing several items within square brackets. myEmptyList = [] # An empty list myOtherList = ["perro", 1, 3.5, "dog"] # A list containing different types
Operating with lists:
myList = [] # Declare an empty list # Now fill it with the append() method. # Enter the Fibonacci series myList.append(1) myList.append(1) myList.append(2) myList.append(3) myList.append(5) myList.append(8) myList.append(15) # This would be equivalent to myList = [1,1,2,3,5,8,15] # Print the number of items in the list print "The list has %d items" % (len(myList)) # Retrieve a specific item in the list print "Item at position 2 is %s" % (myList[2]) # You can retrieve also negative positions print myList[-2] # Create a trimmed version of the list with the : operator. # :X will trim the remove the x items from the end. myTrimmedList = myList[:3] print myTrimmedList # X: will trim the remove the x items from the start. myTrimmedList = myList[2:] print myTrimmedList # We can use [:] to create a full copy of the list myCopyList = myList[:] print "Original and Copy Before Change" print myList print myCopyList # Now change some value in myList myList[0] = 100 print "Original and Copy after Change" print myList print myCopyList #Finally let's make a copy a reverse the list myReversedList = myList[:] myReversedList.reverse() print "List reversed" print myReversedList
We interact with List mainly through methods and properties:
Reference Types
You have to be careful when dealing with lists as they behave quite different from inmutable variables like strings and doubles. Let’s seen an example:
# Declare two variables, make the second equal to the first one myNumber1 = 8 myNumber2 = myNumber1 # Change the first one myNumber1 += 5 # Print both variables print myNumber1 print myNumber2
The result here is something we would expect, the second variable gets the same as the first, then we alter the former but the later stays the same.
Now let’s do something similar with a list of strings:
#Declare a list myList = ["Dog","Cat","Bird","Elephant","Lion","Tiger","Parrot"] # Create the a new list and assign it the contet of myList myCopyList = myList print "Original and Copy Before Change" print myList print myCopyList # Now change some value in myList myList[0] = "Whale" print "Original and Copy after Change" print myList print myCopyList
Look at the result:
Weird right? Despite we only changed the first list, both outputs have been altered. That is because Lists, and Points, Surfaces, Meshes and everything else are Reference-Type variables, meaning that when we called myCopyList = myList; we where not copying the contents of one list into the other but actually linking both variables to the same data, so if we modify one we’ll do so for all of its references.
That’s why, on the previous example, we created the copy of the list not using a plain “=” statement but we added the [:] operator.
Challenge
1. Write a component that checks if a list has an odd number of items and if so, returns the element at the middle.
2. Write your own version of the List Item component.