Python. Remove items at index if item at index starts with word

Hello,

I am trying to do this in python of Dynamo node:

If sublist item at index 5 starts with “word”, then remove item at index 4 of the same sublist
If sublist item at index 8 starts with “word”, then remove item at index 7 of the same sublist
If sublist item at index 10 starts with “word”, then remove item at index 9 of the same sublist

input list: [1,2,3,4,5,“word4”,3,2,“word1”,1,“word21”],[1,2,3,4,5,“word4”,3,2,“word1”,1,“word21”]
output desired=[1,2,3,4,“word4”,3,“word1”,“word21”],[1,2,3,4,“word4”,3,“word1”,“word21”]

I tried this but it does not work

The error gives it away. It’s saying the code ran into an unexpected newline, ie. it hit a new line before it expected one. So if you check before all your new lines… you’ll see you left out the end characters (: in this case) on all but your first loops.

2 Likes

rookie man. Thanks

thanks that was fixed although I get a warning index out of range: 29.

in some cases where the list does not meet the requirements, I believe I get a warning because there are sublists with less items that the requested 29, but not sure if that is the case.

is there any other way to add a condition if that nothing of the conditions exist or they are met, the script does nothing and continues as the original list?

It’s really hard to answer that without seeing your data. There’s probably a more flexible way to handle this with loops rather than specifying indices.

same than the topic sample, in case one of the index, for example lst[10], does not exist, then what else does the script? I had exceptions. In this sample I removed one item so in first sublist there are 10 items and in the second there are 11.
input list: [1,2,3,4,5,“word4”,3,2,“word1”,1],[1,2,3,4,5,“word4”,3,2,“word1”,1,“word21”]

maybe adding to this code something like try, except, pass? I never used it before as I am new in python

I tried this modification, it seems to work but not sure:
image

I know you’ve explained what your data looks like but it’s always best to show it in Dynamo to confirm that everything is working as expected. It also makes it much easier for those of us trying to answer your questions by not requiring a bunch of rework on our end.

You could use a try/except loop but that’s a really heavy-handed solution for something that could just be handled more elegantly.

Are you only concerned with “word” appearing at those specific indices or are you wanting to check all locations? It would be easier to check all indices using a current index and a previous index to remove items when your condition hits. Otherwise, I would suggest checking the list length and including the specific index checks under conditions where the index is within the list length.

The items lengths are unknown, variable, the only thing I know for sure is what I can find in specific indexes, the possibilities, so I am specifying if something starting with a string is found at specific item at index number, then remove it because I do not need it, sometimes the items of sublists are not the same and with this I am trying to remove the unnecessary items.

At a quick glance, your code is flawed, and probably what’s causing your index error.

[1,2,3,4,5,“word4”,3,2,“word1”,1]

You are looking at this list. You grab [5] and then check if it starts with “word”. It does so you then delete the item at index [4].

Let’s go to the next if.
[1,2,3,4,“word4”,3,2,“word1”,1] (This is your new list since at the last if you deleted the item at index [4].
if 1 (item at index 8).startswith(“word”): False

last if
[1,2,3,4,“word4”,3,2,“word1”,1] (same list since the second if was false.
if [10] there is no item at index 10 and thus the error.

You could just do this and ignore the index.

newList = []
for lst in hellowlist:
	sublist = []
	for l in lst:
		if l.startswith("word"):
			pass
		else:
			sublist.append(l)
	newList.append(sublist)

This is the kind of solution I’m talking about. My question about specific indices is in case you have “word” at index 3 but only want to check for instances at 19, 28, and 29. You could add that into the condition but it still feels like an added complication. It also sounds like you want to remove the previous item if you find “word” in your list, which is why I suggested maintaining two indices as you parse your list.

I had thought about that but it was not in the OP so…

If you were to go with the indexes you would need to adjust on the fly as you delete items.

I think something like this. (did it really quick so may not be 100%

newList = []
for lst in hellowlist:
	indexs = [5,8,10]
	count = 0
	for i in indexs:
		if lst[i-count].startswith("word"):
			del lst[i-count-1]
			count += 1
5 Likes

You left out the increment on count, but yeah, that’s a good way to address it.

Thanks Nick,
I adjusted my code above. I do agree with you that my second solution is not great but if it solves the Op very specific problem then great. Would be nice to find a cleaner way though.

1 Like

I think it’s a good solution for what we know about this specific problem. It can always be modified if the workflow changes or new information is added.

1 Like

that makes more sense will try to see how it works, the other simpler thing also worked okay

Hi @ruben.romero,
I agree with @Nick_Boyts to see all in Dynamo would be best to understand what you are trying to achieve. However, here is another solution that may give you more control:

# Load the Python Standard and DesignScript Libraries
import sys
import clr
import re
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# The inputs to this node will be stored as a list in the IN variables.

# Place your code below this line

aList = IN[0]

numsList = []
strList = []

#If you separete your string from your nums then use below code
myIntList = [x for x in aList if isinstance(x, int)]
myStrList = [x for x in aList if isinstance(x, str)]

#if you need to separete further in the string then add the code below
for i in myStrList:
    stringList = "".join(re.split("[^a-zA-Z]*", i))
    strList.append(stringList)
    numbersList = "".join(re.split("[^0-9]*", i))
    numsList.append(numbersList)

# Assign your output to the OUT variable.
OUT = myIntList, myStrList, numsList, strList

Hope this helps!

1 Like

many thanks looks interesting but it is not what I need in this topic. if in specific indexes of a list of sublist I find that those items start with string “word”, then remove those specific items at indexes in all sublists.

1 Like

@ruben.romero no worries! I got it now. Seems like @Steven already found the solution.