How to Handle Variable Input List Length/Nesting in Custom Nodes (Python)

Has anyone found a good method for handling various input types in a custom node? I’m trying to find a python or OOTB solution that allows me to take a variable input (flat list, nested list, single item, etc) and to turn it into the same type of list structure. I tried using flatten and list.join, but that doesn’t work for single items that are not part of a list yet. List.create causes problems for already nested lists. Thoughts?

What are you trying to do? Just get two of any type of list to look the same? Lists are normally organized on a script bases and have a reason for being done the way it was.

You can defiantly use OOTB nodes to organize a list any way you want but it depends on what you want the list to do.

I essentially just need a flat list. The input could be a single item (taken from “Select Model Element” node) a nested list, or a flat list. The goal is to make the node more user-friendly so that one doesn’t have to know the exact nesting required.

Have you tried using list flatten?

Have you tried defining your inputs? That way you’ll enable lacing and as long as there’s a logical way, the Dynamo VM will map the inputs to the function correctly.

This will first make sure to check that the input is for example indeed a point type. Secondly it’ll automatically convert it to a single object, a list or a matrix depending on your definition.

This also works for python scripts, but from my experience it has a negative effect on performance when dealing with large data sets.

Bo, can you post this question on Stack Overflow like I have asked before and I will post some Python examples for your use. :slight_smile: Please reply to this post with a link to SO question.

I’m trying to do the same, but something tells me this i s not the right way:

IsList

Gif01

Here’s a basic example with a python node. The below is two identical scripts, the first one has a defined input as a single object, the second one is left undefined. This way you can skip doing any checks in the python node but as I said earlier, performance will suffer on large data sets(compared to zero touch or built-in nodes) because the python code will have to be re-evaluated for each item:

1 Like

Topic posted here:

1 Like

Dimitar, after reading through your response, I saw that you actually had an answer for the question. I thought that the input nodes only allowed one to structure something of a certain type (point, line, integer) which is why I thought your response would not work for me, but after reading through your response and also Colin McCrone’s post on the blog (http://dynamobim.org/what-does-var-mean/) I see that I can use var[] as the input, which will automatically flatten or create a list to match a flat list structure for any input type. Works great, thanks!

Bo I answered your question @ Stack Overflow. Thanks for posting.

1 Like

Thanks to everyone.

Bo, would you be kind enough and approve the answer on SO if that is indeed an answer that satisfies you. Thank you,

Hello, this thread is very helpful. But can anyone suggest how to do the same in C#?
If I use object it will just recuse the input at the item level, if I use List<object> instead it will ignore nested lists.

What is the equivalent of var[]…[] in C#?

I think that setting the input to List<object> also enables nested lists. Then you would have to play with lacing to get it right. Care to post a sample code + dll of the issue?

Apparently the solution is to use: [ArbitraryDimensionArrayImport] object item

See:

Thanks to:

1 Like

Interesting. Thanks for sharing I didn’t know that one either. It would really make a difference if they posted that stuff somewhere in one place.

@teocomi since there isn’t really a good resource for Zero Touch I have started to collect these little nuances into a blog post. I added your findings to it as well. http://archi-lab.net/tips-tricks-for-zerotouch-libraries-in-dynamo/

3 Likes

The Konrad’s function using lists comprehension:

elements = IN[0]

ProcessLists = lambda function, lists: [ProcessLists(function, item) if isinstance(item, list) else function(item) for item in lists]

sum = lambda x: x + 1

if isinstance(elements, list):
    out = ProcessLists(sum, elements)
else:
    out = sum(elements)

OUT = out

2 Likes

Hi guys ,
Thank you this is very helpful

but trying to change a python code to get variable input but actually with my little experience in python I did not succeed

the python script is provided by @Einar_Raknes by it only take one element as an input

Can anyone please solve this for me just to get more familiar with python scripts

Thank you