Skip to content Skip to sidebar Skip to footer

Python Idiom For Iterating Over Changing List

Is there a better (more obvious/idiomatic) way in python to write an equivalent of index = 0 while index < len(some_list): do_some_stuff(some_list[index]) # may have many si

Solution 1:

You might break up the operations into two separate loops, and use a list comprehension for the second part.

for value in some_list:
    do_some_stuff(value)

some_list = [value for value in some_list if not delete_element(value)]

Another solution would be to iterate over a copy of the list, and use enumerate to keep track of the indices without having to maintain a counter by hand.

for index, value in enumerate(some_list[::-1]):
    do_some_stuff(value)
    if delete_element(value):
        del some_list[-index - 1]

You'd want to iterate backwards so you don't have to adjust index for the deleted elements.

Solution 2:

If order doesn't matter, you can enumerate backwards so that deletes don't mess up the part of the list you haven't processed yet.

for i, item inenumerate(reversed(somelist), -len(somelist)+1):
    do_some_stuff(item)
    if delete_element(item):
        del somelist[-i]

If order does matter, reverse the list, do this trick then reverse it again. That'll confuse 'em!

Depending on the situation, you could replace the item with a marker like None. Either strip it out later or have other places this list is used chack None.

for i, item in enumerate(somelist)):
    do_some_stuff(item)
    if delete_element(item):
        somelist[i] = None

somelist = [item for item in somelist if item]

Solution 3:

you could even, assuming that do_some_stuff returns item, do something like:

res = [item for item in some_list if not delete_element(do_some_stuff(item))]

Solution 4:

The no-nonsense way is to use a generator:

defdo_stuff_and_filter_items(items):
    for item in items:
        do_some_stuff(item)
        ifnot delete_element(item):
            yield item

Then to get an iterable:

items = do_stuff_and_filter_items(items)

or to get a list:

items = list(do_stuff_and_filter_items(items))

or to overwrite the old list:

items[:] = do_stuff_and_filter_items(items)

Post a Comment for "Python Idiom For Iterating Over Changing List"