Houdini & Procedural Workflows / Houdini / Python
Day 6 - Lists in Houdini with Python | Houdini 10 Day Introduction to Python
Written guide

Playing loads YouTube content. YouTube processes data after activation.
Watch on YouTubeIf the player is blocked or unavailable, use Watch on YouTube.
Day six introduces Python lists, then uses indexed node selections to connect a small Houdini network. The practical lesson is that a list’s position and a node’s connector number are different indices, even when both happen to be zero.
The examples below normalize the narrated code into readable Python 3. The exact Houdini and embedded Python versions are unverified. Plain Python examples can run outside Houdini; the hou examples require Houdini and a deliberately prepared selection. The lesson builds a short demonstration, not a general-purpose node-connection tool.
Read list elements by position
At 00:00, create a new shelf tool and open its script editor. A list uses square brackets around comma-separated elements. It can contain numbers, strings, other lists or a mixture of object types. The lesson uses numbers first so the indexing results are easy to follow.
At 02:01, apply the script changes and run the tool, using the Python Shell to inspect output. Index zero retrieves the first element; index one retrieves the second. At 03:03, negative indexing retrieves elements from the end:
numbers = [1, 2, 3, 4, 5]
print(numbers[0]) # 1
print(numbers[1]) # 2
print(numbers[4]) # 5
print(numbers[-1]) # 5
The value at index four is five in this example. Confusing the stored number with its position is an easy mistake when the list contains consecutive numbers. Negative one means the last position; it is useful when the length is not hard-coded, provided the list is not empty.
Summarize, reorder and change a list
At 04:03, use len, min, max and sum on the numeric list. They produce five elements, a minimum of one, a maximum of five and a total of fifteen.
numbers = [1, 2, 3, 4, 5]
print(len(numbers), min(numbers), max(numbers), sum(numbers))
# 5 1 5 15
The fact that lists can hold mixed data does not mean every operation accepts every mixture. The numerical examples use compatible numbers; do not infer that summing strings or ordering unrelated object types will work the same way.
At 05:00, the lesson demonstrates sorting and reversing. Sorting establishes an order by value; reversing flips the existing order. For Python’s exact method behavior, list.sort() and list.reverse() change the list in place, while sorted() produces a new sorted list. Methods that only mutate the list return None, so print the list afterward rather than assigning the result of reverse() back to it. These distinctions are documented in the Python list reference.
At 06:01, append an item to the end, then remove an item by value. A normalized example preserves the source’s duplicate-value lesson:
numbers = [1, 2, 3, 4, 4, 5]
numbers.append(6)
numbers.remove(4)
print(numbers) # [1, 2, 3, 4, 5, 6]
numbers.reverse()
print(numbers) # [6, 5, 4, 3, 2, 1]
remove(4) removes the first matching value, not the element at index four and not every matching value. The remaining four is intentional. Removing a value that is absent raises ValueError; the recording does not add a handler for that case. Python documentation
Convert Houdini’s selected-node tuple when a list is useful
At 07:00, import hou, create a geometry object and add several Null nodes inside it. Call hou.selectedNodes() and print the result. The returned node objects include their paths, allowing the instructor to identify the selection.
At 08:02, the parentheses in the displayed sequence reveal that it is a tuple. SideFX’s function signature confirms the tuple return type. Convert it with list(...) if you want a mutable sequence:
import hou
selected = list(hou.selectedNodes())
print(selected)
This conversion creates a list containing the same node references. It does not duplicate scene nodes. A tuple cannot have its elements reassigned, but the Houdini nodes referenced by those elements can still be edited. Indexing the tuple would also work; the conversion here is a teaching step toward list operations.
Connect nodes with explicit selection and connector indices
At 10:03, the first connection sets input zero of the first selected node to output zero of the second selected node. At 11:01, a second line extends the chain to a third selected node. For the three-node version, begin with three suitable, unconnected Null SOPs in the same editable network:
import hou
selected = list(hou.selectedNodes())
print(selected) # Inspect the returned order before wiring.
selected[0].setInput(0, selected[1], 0)
selected[1].setInput(0, selected[2], 0)
In the first line, selected[0] is the destination node, the first argument 0 is its input connector, selected[1] is the source node, and the last 0 is that source’s output connector. Thus a returned selection ordered A, B, C produces the data-flow chain C → B → A. This follows the documented setInput argument order.
The source disconnects the nodes and changes the selection order to demonstrate different connections. At 12:02, it also observes the order produced by a box selection. Treat that as an observation in the recorded interface, not a reason to assume every selection gesture sorts nodes numerically or spatially. Inspect the returned sequence when connection order matters.
Fewer than three selected nodes makes the second indexing operation invalid. Invalid connectors, different parent networks or locked assets can also prevent wiring; the HOM reference documents those restrictions. The demonstration does not validate arbitrary selections or add error recovery.
Check the resulting wires and their direction after running the prepared example. The useful result is understanding how list positions choose node objects and how connector indices choose their ports. Extending this into a robust tool would require selection checks and broader network handling beyond the two explicit connections shown here.