else in list comp

Brian McErlean b_mcerlean at yahoo.com
Wed Jan 29 12:08:27 CET 2003

```Cliff Wells <clifford.wells at attbi.com> wrote in message news:<mailman.1043815132.31865.python-list at python.org>...
> On Tue, 2003-01-28 at 20:26, Andrew Bennetts wrote:
> > On Tue, Jan 28, 2003 at 08:05:25PM -0800, Cliff Wells wrote:
> > > Maybe this has come up before, but I haven't heard a discussion of list
> > > comps in a while so here's something I thought might be interesting:
> > >
> > > I was looking for a fast, clean way of converting a single value in a
> > > list to a different value (specifically None to '').  It occurred to me
> > > to use a list comp and this seemed the most straightforward solution:
> > >
> > > Given the list:
> > >
> > > l = ['mary', 'had', 'a', 'little', None]
> > >
> > > it should get mapped to ['mary', 'had', 'a', 'little', '']
> >
> > This doesn't solve the general problem, but...
> >
> >     >>> l = ['mary', 'had', 'a', 'little', None]
> >     >>> [x or '' for x in l]
> >     ['mary', 'had', 'a', 'little', '']
>
> Yes, but that wasn't really my point =)  I was soliciting comments on an
> else clause in list comps.

Personally,the syntax you proposed looks confusing to me:
['' for i in l if i is None else i]

Maybe its because it looks a bit like the proposed syntax for a
conditional statement:
(foo) if (cond) else (bar)
and looking at it like this makes me want ot parse it as
['' for i in (l if i is None else i) ]
ie. iterate over list l if i is None, otherwise iterate over list i.

It doesn't seem clear that the "else i" causes the i to replace the
result value, embedded as it is in the list comprehension part.

> Also, consider how to replace None with '' in the following list:
>
> [0, None, '1', None, 2, None, '3']
>
> This is actually closer to my real situation (0 is a possibility). My
> first example was poor.  Sorry.

Obviously you can use
l = [(x is None) and x or '' for x in l]

but thats getting very ugly.  I think a better, and much more generic
approach is a dictionary:

>>> l= [0, None, '1', None, 2, None, '3']
>>> replacements = {None : ''}
>>> print [replacements.get(x,x) for x in l]
[0, '', '1', '', 2, '', '3']

This has the nice property that you can add in multiple substitutions
trivially, just by adding them to the replacement dict.

If you really want a one-liner, you could even use:

[ {None:''}.get(x,x) for x in l]

though you'll lose efficiency since the dictionary will be constructed
each pass.

```