Removal of element from list while traversing causes the next element to be skipped

imageguy imageguy1206 at gmail.com
Tue Jan 29 18:06:26 CET 2008


On Jan 29, 12:34 pm, William McBrine <wmcbr... at users.sf.net> wrote:
> Look at this -- from Python 2.5.1:
>
> >>> a = [1, 2, 3, 4, 5]
> >>> for x in a:
>
> ...     if x == 3:
> ...         a.remove(x)
> ...     print x
> ...
> 1
> 2
> 3
> 5
>
> >>> a
> [1, 2, 4, 5]
>
> Sure, the resulting list is correct. But 4 is never printed during the
> loop!
>
> What I was really trying to do was this:
>
> apps = [name for name in os.listdir(ROOT) if
>         os.path.isdir(os.path.join(ROOT, name))]
>
> apptitles = {}
>
> for name in apps:
>     try:
>         app = __import__(name)
>     except:
>         apps.remove(name)
>     else:
>         apptitles[name] = getattr(app, 'TITLE', name.title())
>
> which worked fine, until I actually had a directory with no module in it.
> Then that directory was correctly removed from the list, but the _next_
> one was skipped, so its title was never assigned, which caused problems
> later in the program.
>
> --
> 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 -- pass it on

You should not change/modify the original sequence iterating over.
In the list comprehension, try changing os.listdir(ROOT) to
os.listdir(ROOT)[:] so you are get a copy of the original list.

geoff.



More information about the Python-list mailing list