Python doesn't remove the same amount of items from two different lists... given the same indices

I’m trying to filtering a list of elements (48 items) and a list of the corresponding parameter values (also 48 items). I have a filter loop written to filter out Null values from the elements list. And an identical filter loop to filter the Parameters list. Yet I get different list lengths depending on which list I filter first. I’ll try to explain here but I’ll also post code below.

Elements >then> list2 and OUT = [len(Elements), len(list2)]
OUT = [45, 46]
and second
list2 >then> Elements and OUT = [len(Elements), len(list2)]
OUT = [47, 46]

This really baffles me. And for reference, I tested this by swapping list2 and Elements on lines 17 and 23. I just want to remove Nulls (that I specify the indices using list2) and this is really throwing me for a loop.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to this node
Elements=[]
list1=IN[0]
list2=IN[0]
member=None
Elements=IN[1]
cnt=len(list1)
indices=[]
output = []

inx=0
while inx<(len(list1)) :
	if list1[inx]==None:
		list2.RemoveAt(inx)
	inx=inx+1

inx=0
while inx<(len(list1)) :
	if list1[inx]==None:
		Elements.RemoveAt(inx)
	inx=inx+1
#	Elements.RemoveAt(inx)#, 

#while(x <= (len(indices))):
#	if indices[x]==

#Elements.RemoveAt(map(indices))

#Assign your output to the OUT variable
OUT = [len(Elements), len(list2)]
#OUT = [list2[::-1], Elements]

Just plain confused

list1 = IN[0]
list2 = IN[0]

This is the same as saying list1 = list2 = IN[0] which means list1 and list2 are the same list, not copies. You can use list2 = list(list1) to make an actual copy.

With all of that being said… just merge the two loops. There’s no reason you should have to duplicate a list just so you can loop through it twice. Just add Elements.RemoveAt(inx) to the first loop. I would also suggest using a for loop rather than a while loop in this case.

I’ll try implementing you’re way of copying. The reason why I didn’t merge the two is that it was giving the same described issue when I tried putting both of the RemoveAt commands in the same line, with a comma between.

They would have to be separate lines.

I just realized another issue you’re going to have is that RemoveAt is altering your list one item at a time. Which means indices won’t line up as soon as you remove an item. You would either have to get a list of indices to delete first and then delete them all at once, or create a new list with the good objects instead of removing the nulls.

1 Like

Oh crud, you’re right. That makes so much sense. I’ll fiddle with it and post an update here.

So here’s what I’ve got now. Thanks for your help!

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import math
#The inputs to this node


lst1=IN[0]
Elements=IN[1]
inx=0
Remove=[]
Output = []
Type =[]
while inx<(len(lst1)):
	if not(lst1[inx] == None):
		Type.append(lst1[inx]), Output.append(Elements[inx])
	inx=inx+1


#Assign your output to the OUT variable
OUT = [Output, Type]