properly delete item during "for item in..."
gherron at islandtraining.com
Thu Jul 17 20:33:28 CEST 2008
> On Jul 17, 9:57 am, mk <mrk... at gmail.com> wrote:
>> Gary Herron wrote:
>>> You could remove the object from the list with
>>> del myList[i]
>>> if you knew i. HOWEVER, don't do that while looping through the list!
>>> Changing a list's length will interact badly with the for loop's
>>> indexing through the list, causing the loop to mis the element following
>>> the deleted item.
>> Jumping into a thread, I know how not to do it, but not how to do it
>> Iterating over a copy may _probably_ work:
>> >>> t=['a', 'c', 'b', 'd']
>> >>> for el in t[:]:
>> del t[t.index(el)]
>> >>> t
>> However, is it really safe? Defining safe as "works reliably in every
>> corner case for every indexable data type"?
>> Con: suppose the data structure t is really, really big. Just deleting
>> some items from t temporarily doubles the memory consumption.
> Would this work (safely) then? It does in my test cases but that of
> course doesn't prove it works in a general case...
> for item in myList:
No. Same problem, The for loop iterates through the list by keeping
and incrementing an internal index. Any modification of the list does
not change the index correspondingly.
One proper way:
newList = 
for item in myList:
if ... whatever...
myList = newList
Another, using list comprehension (it's the same thing really as the above):
myList = [item for item in myList if ... whatever...]
> For dictionaries we can just iterate over values() or items() as
> opposed to itervalues() or iteritems() since that's technically a copy
> of values or items in the dict, right?
No! In fact the whole point of iteritems and itervalues and iterkeys is
that they *DO NOT* make copies, so changing the dictionary out from
under them is a programming error.
If you use dict.items(), dict.keys() or dict.values(), then you're OK,
because these methods *do* create new lists for both.
More information about the Python-list