Okay, I seem to be having a real brain moment. Given two inputs, which are equal length lists (of varying internal length), how can I do a dict/zip type operation in the GhPython component whereby one input is going to be a dictionary key, and one is going to be a value?
In the below case, a list of vertices that are keyed by a name The grasshopper implicit cycle means that the some dictionary.update() has no purpose, right? If I make a dictionary I don’t see how it doesn’t just get overriden every single time.
So it should be {cyl_slot_1: verts, cyl_slot_0: verts}
My wish is to be able to use the list of names as keys, and the associated list of points as values, in a python dictionary which could then be written into a JSON file of keys and values.
From my search so far, I am seeing a few possible routes and patterns emerging around ghpythonlib.treehelpers and the tree_to_list method, but I must admit I feel like I am missing something for such a basic operation.
What I’m gathering so far is that dictionaries don’t seem to play too nicely in the ghpython component, unless I’m mistaken, or at least that I need to slice and dice the trees a little before manipulating into a dictionary.
Well … that’s a classic - simple - puzzle addressed (general case) as follows:
Data: A custom Object collection is required (where Object is an entity build via a Class). Define suitable Properties related with something (that could be flat and/or nested: an item (of any Type), a collection (ditto), a higher order set, a cat, a dog etc etc) containing pieces of data of interest and off you go. So your Object could contain a rather unlimited (kinda) amount of information instead of just a value/key combo. Obviously (case: many code modules around as we do in real-life) you’ll need a robust Unboxing approach (i.e. reading similar collections from one piece of code to another). That said that’s hard only if you have Point3d AND Vector3d Types.
Data mining: You can do any imaginable flat/nested Queries on the fly (that’s rather the main benefit of the whole Object oriented approach) via LINQ/PLINQ.
Data management: Now … if your collection creation proccess is interactive/dynamic (on a per code cycle basis) you should swap volatile <> persistent data according some rules - in plain English: what is “overrriden” (or not) it’s up to you (an Event driven thing. that is) If you want an entry level (so to speak) demo in C# notify - but you can’t auto translate C to P.
Edit: You probably want to only use the first item in the keys branch as dict key:
# Cast tree branches to hashable Python lists (i.e. tuples)
keys = [tuple(b) for b in K.Branches]
vals = [tuple(b) for b in V.Branches]
# Structure data in dictionary
d = {}
for k,v in zip(keys,vals):
d[k[0]] = v
# Wrap dictionary to prevent unrolling to keys on output
D = [d,]
Perfection. Very helpful, Anders. 6 months-ish without opening Grasshopper has really taken its toll. It looks like the rule of thumb, then, is that if I want to treat things ‘statically’ I need to do this input node trees >>> regular python types conversion. It looks like I will need to take a lot of extra care if what I’m handling gets larger.
Does this relate to d[k[0]] = v ? Yeah I see there that before it made a dict with tuples as keys. Which is nice too I guess, I didn’t know until recently that that was an option actually.
And deeper doth the rabbit hole delve So many questions still it feels, the journey of discovery goes on. Unrelated, why do JSON and XML libraries not come up in the autocomplete for imports but they are available?
It really depends on the case. But a good GHPython rule of thumb is to treat lists as lists and trees as trees explicitly (i.e. don’t use implicit cycles outside simple cases, there are more good reasons such as performance). For instance, in your case the keys could be a flat list and the code could be reduced to this:
No problem at all. This was a really good, concise and to the point solution. I made the mistake of feeling that the structure I had to begin with, a (kinda) list and (kinda) list of lists would get me where I needed. In the end, no matter what combination of item/list access and flattening/grafting I did was ever going to make a difference! In a sense it’s going back to basics and respecting the trees. I’m more surprised to have not faced this kind of situation before, given it is a really trivial object to produce.
This programming lark really isn’t for the faint of heart. Sometimes I wish I stayed in my lane modelling and rendering. Maybe this was one of those situations where it’s plain sailing in C#, and painful in python.
One other thing; is this referring to the output parameters in the ghPython node?
I notice the var ‘d’ outputs as the keys, and the var ‘D’ outputs as the IronPython thing. Am I right in thinking, this is because grasshopper at this point is now trying to return to the data tree structure instead?
So a list of one thing (the dict) gives a branch with a one item long list
whereas the dictionary outputted directly is translated to a branch with a list of 12 items, which in this case are the keys (similar to if you iterated for _ in dict: print _ without adding .items() and tuple unpacking?
It’s not really a question of language, but one of editors. Where I think you’d find that the C# script editor will likely give you substantially more severe headaches (see e.g. these topics 1, 2, 3) Hopefully the new common RhinoCode editor will help to alleviate these issues.