altering an object as you iterate over it?

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Fri May 19 22:51:07 EDT 2006


John Salerno a écrit :
> John Salerno wrote:
> 
>> What is the best way of altering something (in my case, a file) while 
>> you are iterating over it? I've tried this before by accident and got 
>> an error, naturally.
>>
>> I'm trying to read the lines of a file and remove all the blank ones. 
>> One solution I tried is to open the file and use readlines(), then 
>> copy that list into another variable, but this doesn't seem very 
>> efficient to have two variables representing the file.
>>
>> Perhaps there's also some better to do it than this, including using 
>> readlines(), but I'm most interested in just how you edit something as 
>> you are iterating with it.
>>
>> Thanks.
> 
> 
> Slightly new question as well. here's my code:
> 
> phonelist = open('file').readlines()

readlines() reads the whole file in memory. Take care, you may have 
problem with huge files.

> new_phonelist = phonelist

Woops ! Gotcha ! Try adding this:
assert(new_phonelist is phonelist)

Got it ? Python 'variables' are really name/object ref pairs, so here 
you just made new_phonelist an alias to phonelist.

> 
> for line in phonelist:
>     if line == '\n':

replace this with:
       if not line.strip()

>         new_phonelist.remove(line)

And end up modifying the list in place while iterating over it - which 
is usually a very bad idea.

Also, FWIW, you'd have the same result with:

phonelist = filter(None, open('file'))

> import pprint
> pprint.pprint(new_phonelist)
> 
> But I notice that there are still several lines that print out as '\n', 
> so why doesn't it work for all lines?

Apart from the fact that it's usually safer to use line.strip(), the 
main problem is that you modify the list in place while iterating over it.



More information about the Python-list mailing list