properly delete item during "for item in..."

Gary Herron gherron at islandtraining.com
Thu Jul 17 14:33:28 EDT 2008


Ratko wrote:
> 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
>> properly?
>>
>> 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:
>     myList.remove(item)
>   

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...
     newList.append(item)
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.

Gary Herron

>
> R
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>   




More information about the Python-list mailing list