0

I need to update a list while it is being iterated over. Basically, i have a list of tuples called some_list Each tuple contains a bunch of strings, such as name and path. What I want to do is go over every tuple, look at the name, then find all the tuples that contain the string with an identical path and delete them from the list.

The order does not matter, I merely wish to go over the whole list, but whenever I encounter a tuple with a certain path, all tuples (including oneself) should be removed from the list. I can easily construct such a list and assign it to some_list_updated, but the problem seems to be that the original list does not update...

The code has more or less the following structure:

for tup in some_list[:]:
    ...
    ...somecode...
    ...
    some_list = some_list_updated

It seems that the list does update appropriately when I print it out, but python keeps iterating over the old list, it seems. What is the appropriate way to go about it - if there is one? Thanks a lot!

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Michał Czapliński
  • 1,332
  • 1
  • 14
  • 24
  • You are looping over a **copy** of the list, so the behaviour you see is entirely expected. – Martijn Pieters Aug 15 '13 at 14:02
  • How about you tell us what you are trying to do? Usually a list comprehension (build a new list from another sequence) is the better approach. – Martijn Pieters Aug 15 '13 at 14:02
  • Thanks for the quick replies! Basically, i have a list of tuples; each tuple contains a bunch of strings, such as name and path. What I want to do is go over every tuple, look at the name, then find all the tuples that contain the string with an identical path and delete them from the list. @iCodez As far as I know you shouldn't iterate over the list itself because that might lead to unspecified behaviour... – Michał Czapliński Aug 15 '13 at 14:13
  • You can [edit] your question to clarify what you are asking. – Martijn Pieters Aug 15 '13 at 14:17
  • Are you trying to make your entries unique? Is order important? Or should any items that have identical paths *all* be removed? – Martijn Pieters Aug 15 '13 at 14:18

1 Answers1

1

You want to count the paths using a dictionary, then use only those that have a count of 1, then loop using a list comprehension to do the final filter. Using a collections.Counter() object makes the counting part easy:

from collections import Counter

counts = Counter(tup[index_of_path] for tup in some_list)

some_list = [tup for tup in some_list if counts[tup[index_of_path]] == 1]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for your help - I'm on python 2.6 and cannot upgrade easily so the Counter class is not included in the release. Actually I found the solution in an answer to an almost identical problem here: http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python?lq=1 – Michał Czapliński Aug 15 '13 at 17:06
  • @MichałCzapliński: There is a backport available, see [Counter in Collections module Python](http://stackoverflow.com/a/13311111) :-) – Martijn Pieters Aug 15 '13 at 19:46