Python script won't work with lists

python
#1

I’ve just started out using python, so I apologies in advance if nothing makes sense!

I’ve made a couple of scripts to aid dynamo, and just to see if i could make them for learning purposes.

The one below works with a list, but not a list of lists. It is used to remove all the chars a-z from a string:

import re

a = []

for i in IN[0]:

    b = re.sub("[a-zA-Z]+", "", i)
    a.append(b)

#Assign your output to the OUT variable.
OUT = a

When I input a list of lists it returns ‘null’ with an error saying:

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 7, in
TypeError: expected string for parameter ‘string’ but got ‘list’

A different script works with lists in my IDE but not in dynamo, it just returns null.
So in my IDE i have this:

y = [1234, 5678]

def digit_test(n):
    sum_n = []
    for i in n:
        total = 0
        while i>0:
            total += (i%10)
            i = i//10
        sum_n.append(total)
    return sum_n

print digit_test(y)

>>> returns [10, 26]

But in dynamo I have the below, as the above returns null in dynamo:

import clr

n = IN[0]

def digit_sum(n):
    sum_n = 0
    while n>0:
        sum_n += (n%10)
        n=n//10
    return sum_n

OUT = digit_sum(n)

Does anyone have any idea? I’m getting the hang of using python in my IDE, but struggling a tad with it in dynamo, so i’m just trying to get used to using it in the dynamo environment as well.

Thanks for reading,

TJ

0 Likes

#2

What is your input in Dynamo? From what I see the input is a list of strings? Seems that you miss a for loop somewhere on your script, probably wrapping the while statement.

Would be clearer with a snapshot of your Dynamo graph, or the graph itself.

0 Likes

#3

Yes i’m inputting strings, this is the first script which works with only one list, any more and it crashes with the warning shown in my first post:

This is the third script shown above:

Which returns null when I input more than one item.

Cheers

0 Likes

#4

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 16, in
File “”, line 8, in digit_test
TypeError: iteration over non-sequence of type int

Not sure what I’m doing wrong with the top one

0 Likes

#5

first script:

Your input is a list of list - so the code should reflect that. Try:

import re
out = []
for l in IN[0]:
    temp = []

    # l is the sublist
    for i in l:

         # now i is each string
         b = re.sub("[a-zA-Z]+", "", i)
         temp.append(b)

    out.append(temp)
OUT = out

with this, you can connect item from List.GetITemAtIndex directly to Python IN[0]. No need to use l[3] to get one list.

code block having Ironpython error:

Your input IN[0] is an integer 1234, so the 3rd line of digit_test “for i in n” will not work. You cannot loop over a single integer - that is what the warning message said. To make it work, just wrap 1234 with [] to make a list with one item - list can be iterated over.

0 Likes

Calling FamilyInstance.ByPoint from Python
#6

@yyi is right. The problem here is that the code doesn’t accept different types of inputs (single integer or list of integers, single list of strings or nested lists, etc.)

What I would do is adapt the code to the worst case scenario for each case, being this when you have nested list of strings for the first one and a list of integers for the second. Pay attention to the if statement using isinstance().

Remove Characters

import re

inputList = IN[0]
outputList = []

def RemoveCharacters(listOfItems):
	tempList = []
	for i in lst:
	    b = re.sub('[a-zA-Z]+', '', i)
	    tempList.append(b)
	return tempList

#This will wrap the input inside a list in case the input is
#not a list of nested lists.
if not isinstance(inputList[0], list):
	inputList = [inputList]

for lst in inputList:
	processedList = RemoveCharacters(lst)
	outputList.append(processedList)

#Assign your output to the OUT variable.
OUT = outputList

Sum

inputList = IN[0]
outputList = []

def digit_sum(n):
    sum_n = 0
    while n>0:
        sum_n += (n%10)
        n=n//10
    return sum_n


#This will wrap the input  inside a list in case the input is
#not a list.
if not isinstance(inputList, list):
	inputList = [inputList]
	
	
for n in inputList:
	processed = digit_sum(n)
	outputList.append(processed)

#Assign your output to the OUT variable.
OUT = outputList

4 Likes

Python Nodes Basics
Python Nodes Basics
#7

You two are stars! I’ve just got back from work so I’ll try and get my head around what’s going on here later tonight.

Thanks for taking the time to read through my problem, hopefully python will come easier to me soon.

0 Likes

#8

You can also wrap your Python code in a custom node and use lacing.

1 Like

#9

That’s brill, cheers. I didn’t understand the isinstance() at first, but i’ve had a good practice today, slowly getting my head around all this.

Thanks for all the help.

TJ

0 Likes