Lesson 3.3Lesson 3.3 · Data Trees & List Management
Tree Matching & Grafting
Graft, Flatten, Simplify - and the data-matching rules behind '400 lines instead of 20'
You expected 20 lines. Grasshopper gave you 400. Nothing is broken - your two inputs just matched every-with-every.
This is the lesson that stops the tears. Almost every 'Grasshopper is doing something insane' moment - duplicated geometry, a count that exploded, lines connecting to the wrong things - traces back to how two inputs got matched.
Once you understand Graft, Flatten and Simplify, and the three matching rules that govern how components pair up their inputs, these mysteries turn into one-move fixes. This is the single most practical skill in the whole module.
Diagnose first: Param Viewer on BOTH inputs. Then reshape. Graft to separate, Flatten to merge, Simplify to tidy.
Graft, Flatten, Simplify: your three everyday moves
Three components reshape trees, and you will use them constantly. Learn what each does to the structure, not just its name.
Graft pushes every item onto its own new branch. A single list of 20 points becomes a tree of 20 branches, one point each. Why would you want that? Because it changes how the data matches downstream - grafting is how you say 'treat each of these separately, and pair each one against the whole of that other input'. It is the go-to move for making a list behave like a set of independent cases.
Flatten does the opposite: it collapses every branch back into one single list, discarding the path structure entirely. All items, one branch, in order. Flatten is the sledgehammer - wonderfully effective for forcing everything into one clean stream, and dangerous precisely because it throws away the grouping you may have needed. Reach for it deliberately, never reflexively.
Simplify is the gentle one: it removes redundant, shared levels from the paths without moving any item. If every branch is buried under a common prefix like {0;0;0;...}, Simplify strips the parts that don't distinguish anything, turning unreadable deep paths into clean {0}, {1} - while the data stays exactly where it was. It tidies labels, not contents. Together these three - split, merge, tidy - are the vocabulary of every tree fix you will make.
Graft = split every item onto its own branch. Flatten = dump all into one list. Simplify = clean the path labels only.
Data matching: how components pair their inputs
Now the heart of it. When a component has two or more inputs of different lengths - say 3 points and 5 circles - it has to decide how to pair them. Grasshopper follows a data-matching rule, and knowing which rule is in play explains nearly every surprising result.
The default is longest-list: Grasshopper walks the longest input and reuses the last item of the shorter ones to keep up. Pair 3 planes with 5 radii and you get 5 circles - the last plane repeated to cover the extra radii. Usually sensible, occasionally surprising.
Shortest-list matching stops at the end of the shortest input: 3 planes and 5 radii give only 3 circles, and the two extra radii are simply dropped. You opt into this (via the Shortest List component or a component option) when you want strict, one-to-one pairing with no reused leftovers.
Cross reference is the dramatic one: it pairs every item of one input with every item of the other. 3 points crossed with 5 points produces 15 combinations - the full grid. This is enormously useful when you genuinely want all combinations (every column position against every row position to build a grid), and it is the usual culprit when a count explodes far beyond what you expected. If you asked for 20 and got 400, a cross reference - deliberate or accidental - almost certainly happened.
'Why 400 lines instead of 20?' - the classic, explained
Let's solve the archetypal disaster properly, because understanding it once immunises you. You have 20 points on one wire and 20 points on another, and you feed both into a Line component expecting 20 lines - one connecting each pair. Instead you get 400. What happened?
One of your inputs is a tree and the other is a flat list - and when a tree meets a list, the component often matches the flat list against each branch of the tree, which multiplies. Twenty branches each matched against a 20-item list gives 20 x 20 = 400. Grasshopper didn't misbehave; it faithfully paired every branch with the whole other input. Your two inputs simply had mismatched structures.
The fix is to make the structures agree. If both should be simple parallel lists, Flatten both inputs so each is one 20-item list, and you'll get the 20 one-to-one lines you wanted. If you meant for the pairing to be per-branch, Graft the flat input so it, too, has one item per branch and the branches align one-to-one. The move is always the same diagnosis: open the Param Viewer on both inputs, compare their shapes, and use Graft or Flatten to bring them into alignment. The geometry was never the problem - the data structures were.
400 = 20 x 20. A tree met a flat list and matched branch-by-list. Flatten both, or graft to align.
Trim Tree, Prune and matching with intent
A few more tools round out the kit. Trim Tree removes the last N levels of a path, merging the deepest branches back together - the surgical opposite of Graft when you've branched one level too far and want to fold it back without flattening everything. Think of it as 'undo one level of nesting' rather than the total collapse Flatten performs.
Prune Tree (and related tools like Clean Tree) remove empty branches or null items that quietly accumulate and cause off-by-one mismatches later - a good habit before a tricky match. And the Path Mapper is the power tool for those who need to rewrite path structure explicitly, remapping {A;B} to {B} or {A} with a rule; you won't need it often, but it's there when Graft and Flatten aren't precise enough.
The deeper point is to work with intent. Before wiring two things together, ask: what shape is each input, and what pairing do I actually want - one-to-one, one-to-many, or all-combinations? Then set the structures to make that happen: Flatten for one clean stream, Graft to separate cases, Simplify to keep paths readable, Trim to fold a level back. Most 'Grasshopper is fighting me' sessions are really just a mismatch between the pairing you imagined and the one the data structures dictated. Name the pairing you want, shape the trees to match, and the fight ends.
A field guide: which move for which pairing
Let's turn all of this into a decision you can make in seconds at the canvas, because in practice the whole skill collapses to one question asked before you wire two things together: what pairing do I actually want?
One-to-one - each item of A with the matching item of B, same count out. Make both inputs the same shape: if both are flat lists of equal length, you're done (longest-list keeps them in step); if one is a tree, Flatten both or Graft both so their branch structures agree. This is the everyday case - 20 planes with 20 radii giving 20 circles.
One-to-many - each item of A combined with the whole of B. Graft A so each of its items sits alone on its own branch; each branch then matches against the entire list B. This is how you say 'for each attractor point, measure the distance to every grid point' - graft the attractors, leave the grid flat.
All-combinations - every item of A with every item of B, N times M results. Use a cross reference (or the grafting that induces one). This is a grid generator: every X coordinate against every Y coordinate. Expect and want the count to multiply here.
Carry a tiny pre-flight checklist: (1) Param Viewer on both inputs - list or tree, how long? (2) name the pairing I want in words; (3) reshape to make the structures deliver it; (4) Simplify to keep paths readable. Four beats, every time. Do this and the 'Grasshopper is fighting me' feeling essentially disappears - you'll have replaced surprise with a deliberate choice, which is exactly what separates someone who uses trees from someone who is used by them.
Graft
Puts every item onto its own new branch
Turns a list of N into a tree of N single-item branches. Used to make items match as independent cases.
Flatten
Collapses all branches into one flat list
Discards path structure entirely. Powerful and blunt - use deliberately, because it destroys grouping you might need.
Simplify
Removes redundant shared levels from paths
Tidies path labels without moving any item. Turns unreadable deep paths into clean {0}, {1}.
Trim Tree
Removes the last N levels of the path
Folds the deepest branches back together. The surgical 'undo one graft' rather than a full flatten.
Data matching (longest / shortest / cross reference)
The rules for pairing inputs of different length
Longest reuses the last item; shortest drops leftovers; cross reference pairs every-with-every. Explains almost every surprising count.
Workshop — cause the 400-line explosion, then fix it
The best way to never fear this bug again is to create it on purpose, diagnose it with the Param Viewer, and fix it two different ways. You'll come away able to control matching with intent.
Rhino + Grasshopper. Param Viewer and Panel on both inputs. Series, Construct Point, Line, Graft, Flatten.
Goal: reproduce and fix a data-matching explosion Inputs: Rhino + Grasshopper Time: ~40 minutes
- 1Make two point lists: use two Series/Construct Point setups to place 5 points along X and 5 points along Y (both flat lists of 5).
- 2Wire both into a Line component and read the output count. With both flat and equal length you'll get 5 lines (longest-list, in step). Confirm in a Panel.
- 3Now Graft the X points and re-wire. Read the count - it jumps to 25, because each grafted X branch now matches against the whole 5-item Y list (a cross reference in disguise). Param-View both inputs and see the structural mismatch.
- 4Fix it two ways and compare: (a) Flatten both inputs to get back the 5 one-to-one lines; (b) Graft the other input too so the branches align one-to-one. Note which fix preserves the grouping you'd want for a grid versus a fan.
- 5Write the diagnosis in one sentence, in the form: 'Input A was a tree of 5 branches, input B a flat list of 5, so the component matched branch-by-list = 25; flattening both restored one-to-one.'
You’ll walk away with
One definition that demonstrates the explosion and both fixes side by side, plus your one-sentence diagnosis. Being able to _state_ the mismatch is the real deliverable - it's the sentence you'll reuse on every future bug.
Three altitudes on the same idea
Read the band that fits you — or all three.
This is the skill that makes big facades behave. Panelising a tower means constantly deciding whether a shading rule applies per-panel, per-floor, or across the whole surface - which is entirely a matching-and-grafting decision. Master Graft, Flatten and cross reference and you can direct exactly how a rule propagates through thousands of elements instead of fighting mysterious multiplications.
When a pattern suddenly repeats too many times, this lesson is the cure. A tiling that should map one motif per cell but instead stamps every motif in every cell is a cross-reference match - and a Flatten or Graft fixes it in one move. Controlling how your data pairs up is what keeps a decorative system producing the count and arrangement you actually drew.
Learn to read the Param Viewer on _both_ inputs before you panic - that single habit is worth more than memorising components. Almost every 'my definition is broken' moment in your first year is a matching mismatch. Being the person who calmly says 'one input is a tree, the other's a list - flatten both' will make you look far more experienced than you are.
“When I get way too many results, some component must be bugged or duplicating my geometry.”
Do it yourself
Predict the count before you check.
- 13 planes and 5 radii into a Circle component with default matching - how many circles, and why?
- 2Same inputs with shortest-list matching - how many now, and what happened to the extras?
- 3In one sentence, what does Graft do to a flat list of 12 items?
- 4You got 400 lines from two 20-item inputs. What's the most likely structural cause?
- 5Which reshaping component tidies path labels without moving any data?
The one line to carry out
Peer-reviewed journals & authoritative standards
- 01Rhino Developer — Grasshopper Data Trees — Robert McNeel & Associates, 2026.
- 02Mode Lab — The Grasshopper Primer (Third Edition) — grasshopperprimer.com (free online edition), 2020.
- 03Grasshopper Docs — component reference — grasshopperdocs.com, 2026.
- 04Rutten, D. — The Guide to Grasshopper (community) — grasshopper3d.com, 2026.
You can now read and reshape trees fluently - which means your definitions are about to get bigger and more ambitious. The final lesson of this module is about keeping that growing complexity legible: groups, scribbles, clusters, colour, naming, and a real debugging strategy so large definitions stay understandable.
The author
Amogh N P
Architect, interior designer, and creative polymath. Studio Matrx began in his notebooks — his vision of design made honest, useful, and open to everyone. Its Academy is written and taught in his memory, and free, forever.
More about Amogh →