Remove empty strings from list
Steven D'Aprano
steven at REMOVE.THIS.cybersource.com.au
Mon Sep 14 23:58:18 EDT 2009
On Mon, 14 Sep 2009 18:55:13 -0700, Chris Rebert wrote:
> On Mon, Sep 14, 2009 at 6:49 PM, Helvin <helvinlui at gmail.com> wrote:
...
> > I have looked at documentation, and how strings and lists work, but I
> > cannot understand the behaviour of the following:
...
> > for item in list:
> > if item is ' ':
> > print 'discard these: ',item
> > index = list.index(item)
> > del list[index]
...
> Moral: Don't modify a list while iterating over it. Use the loop to
> create a separate, new list from the old one instead.
This doesn't just apply to Python, it is good advice in every language
I'm familiar with. At the very least, if you have to modify over a list
in place and you are deleting or inserting items, work *backwards*:
for i in xrange(len(alist), -1, -1):
item = alist[i]
if item == 'delete me':
del alist[i]
This is almost never the right solution in Python, but as a general
technique, it works in all sorts of situations. (E.g. when varnishing a
floor, don't start at the doorway and varnish towards the end of the
room, because you'll be walking all over the fresh varnish. Do it the
other way, starting at the end of the room, and work backwards towards
the door.)
In Python, the right solution is almost always to make a new copy of the
list. Here are three ways to do that:
newlist = []
for item in alist:
if item != 'delete me':
newlist.append(item)
newlist = [item for item in alist if item != 'delete me']
newlist = filter(lambda item: item != 'delete me', alist)
Once you have newlist, you can then rebind it to alist:
alist = newlist
or you can replace the contents of alist with the contents of newlist:
alist[:] = newlist
The two have a subtle difference in behavior that may not be apparent
unless you have multiple names bound to alist.
--
Steven
More information about the Python-list
mailing list