Removal of element from list while traversing causes the next element to be skipped
Paul Hankin
paul.hankin at gmail.com
Tue Jan 29 17:49:09 EST 2008
On Jan 29, 4: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.
How about...
for name in apps:
try:
app == __import__(name)
apptitles[name] = getattr(app, 'TITLE', name.title())
except ImportError:
pass
# Remove apps with no title, ie those that didn't import.
apps = [name for name in apps if apptitles.get(name)]
Alternatives for the last line would be 'apps = filter(apptitles.get,
apps)'
or 'apps = apptitles.keys()'.
--
Paul Hankin
More information about the Python-list
mailing list