Replace Sublist with Sublist at Index

Two lists of differing lengths where each element in the list is another list, and a list of index values whose length matches the smaller list. I want to replace items in the longer list, with items in the smaller list based on the list of index values. I assumed List.ReplaceItemAtIndex would do the trick but no. Instead of replacing items in the longer list at the top level, it drills down to the sublists and replaces items there. The list at the end should be the same length as the original list not the length of the smaller list.

I can get close, I think, with Python, but I’m getting an out of index error (which makes sense… I just don’t know how to resolve it).

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN

original = UnwrapElement(IN[0])
collapsed = UnwrapElement(IN[1])
location = IN[2]

output = []
index = []

n=0
loc=0
for each in original:
if n == location[loc]:
	output.append(collapsed[loc])
	loc += 1
else:
	output.append(original[n])
n += 1

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

I read something about needing an imperative (sp?) operation but that’s beyond my skill set right now.

In your List.ReplaceItemAtIndex node have you tried changing the lacing to longest?

@Greg_McDowell
I posted a similar issue below.
Try if the solution works with list of lists.

An example of an imperative code block that does the needful…

def MulRep(lst:var[]..[],
idx:var[]..[],itm:var[]..[])
{
return=[Imperative]
	{
	c=0;
	for (i in idx)
		{
		lst[i]=itm[c];
		c=c+1;
		}
	return=lst;
	}
};
3 Likes

I took the python from Clockwork and got it to work but I don’t really know why it works.

before –

_list = IN[0]
rValues = IN[1]
iValues = IN[2]
if len(iValues) > 1 and len(rValues) == 1:
rValues = [rValues[0]] * len(iValues)
for (index, value) in zip(iValues, rValues):
_list[index] = value
OUT = _list

after –

_list = UnwrapElement(IN[0])
rValues = UnwrapElement(IN[1])
iValues = UnwrapElement(IN[2])
if len(iValues) > 1 and len(rValues) == 1:
rValues = [rValues[0]] * len(iValues)
for (index, value) in zip(iValues, rValues):
_list[index] = value
OUT = _list
1 Like

Thanks.

Does Imperative mean something like “do this once, then do it again using the results of the previous step as a new set of inputs”?

I have another challenge (more complicated) where I need to use the output of a series of actions as an input to the same series of actions over a series items in a series of lists. Is this a use of Imperative and can it be done with nodes rather than all in DS or Python?