Velocity Reviews > else condition in list comprehension

# else condition in list comprehension

Luis M. Gonzalez
Guest
Posts: n/a

 01-09-2005
Hi there,

I'd like to know if there is a way to add and else condition into a
list comprehension. I'm sure that I read somewhere an easy way to do
it, but I forgot it and now I can't find it...

for example:
z=[i+2 for i in range(10) if i%2==0]
what if I want i to be "i-2" if i%2 is not equal to 0?

Reinhold Birkenfeld
Guest
Posts: n/a

 01-09-2005
Luis M. Gonzalez wrote:
> Hi there,
>
> I'd like to know if there is a way to add and else condition into a
> list comprehension. I'm sure that I read somewhere an easy way to do
> it, but I forgot it and now I can't find it...
>
> for example:
> z=[i+2 for i in range(10) if i%2==0]
> what if I want i to be "i-2" if i%2 is not equal to 0?

You'll have to add the condition at the front:

z = [(i+2, i-2)[i%2] for i in range(10)]

should do what you need.

Reinhold

Matteo Dell'Amico
Guest
Posts: n/a

 01-09-2005
Luis M. Gonzalez wrote:
> Hi there,
>
> I'd like to know if there is a way to add and else condition into a
> list comprehension. I'm sure that I read somewhere an easy way to do
> it, but I forgot it and now I can't find it...
>
> for example:
> z=[i+2 for i in range(10) if i%2==0]
> what if I want i to be "i-2" if i%2 is not equal to 0?

You could use

[(i-2, i+2)[bool(i%2 == 0)] for i in range(10)]

or, in a less general but shorter way

[(i+2, i-2)[i%2] for i in range(10)]

or even

[i%2 and i-2 or i+2 for i in range(10)]

The "if" clause in comprehensions is used as a filter condition.

--
Ciao,
Matteo

Luis M. Gonzalez
Guest
Posts: n/a

 01-09-2005
Thank you guys!

Reinhold Birkenfeld
Guest
Posts: n/a

 01-09-2005
Matteo Dell'Amico wrote:
> Luis M. Gonzalez wrote:
>> Hi there,
>>
>> I'd like to know if there is a way to add and else condition into a
>> list comprehension. I'm sure that I read somewhere an easy way to do
>> it, but I forgot it and now I can't find it...
>>
>> for example:
>> z=[i+2 for i in range(10) if i%2==0]
>> what if I want i to be "i-2" if i%2 is not equal to 0?

>
> You could use
>
> [(i-2, i+2)[bool(i%2 == 0)] for i in range(10)]
>
> or, in a less general but shorter way
>
> [(i+2, i-2)[i%2] for i in range(10)]
>
> or even
>
> [i%2 and i-2 or i+2 for i in range(10)]

One should note that the (cond and X or Y) construct only works if X can
never produce a false value (such as 0, "", []). In this example, it is
okay, but replace 2 with 1 and you will run into trouble for i = 1.

Reinhold

Dan Bishop
Guest
Posts: n/a

 01-09-2005
Luis M. Gonzalez wrote:
> Hi there,
>
> I'd like to know if there is a way to add and else condition into a
> list comprehension. I'm sure that I read somewhere an easy way to do
> it, but I forgot it and now I can't find it...
>
> for example:
> z=[i+2 for i in range(10) if i%2==0]
> what if I want i [sic] to be "i-2" if i%2 is not equal to 0?

z = [i + (2, -2)[i % 2] for i in range(10)]

In general, the expression "T if C is true, or F if C is false" can be
written as (F, T)[bool(C)]. (If you know that C will always be either
0 or 1, as is the case here, the "bool" is redundant.)

Unless, of course, either F or T has side effects. For a side-effect
free expression, you can use (C and [T] or [F])[0] or one of the many
other ternary operator substitutes. (Search for PEP 308.)

It's me
Guest
Posts: n/a

 01-10-2005
> z = [i + (2, -2)[i % 2] for i in range(10)]

But then why would you want to use such feature? Wouldn't that make the
code much harder to understand then simply:

z=[]
for i in range(10):
if i%2:
z.append(i-2)
else:
z.append(i+2)

Or are we trying to write a book on "Puzzles in Python"?

Luis M. Gonzalez
Guest
Posts: n/a

 01-10-2005
It's me wrote:
> > z = [i + (2, -2)[i % 2] for i in range(10)]

>
> But then why would you want to use such feature? Wouldn't that make

the
> code much harder to understand then simply:
>
> z=[]
> for i in range(10):
> if i%2:
> z.append(i-2)
> else:
> z.append(i+2)
>
> Or are we trying to write a book on "Puzzles in Python"?

Once you get used to list comprehensions (and it doesn't take long),
they are a more concise and compact way to express these operations.
I think that writing 6 lines instead of 1 could be more readable of you
are a beginner, but after playing a little bit with listcomps for the
first time, you'll see they are very practical yet readable.

Steven Bethard
Guest
Posts: n/a

 01-10-2005
Luis M. Gonzalez wrote:
> It's me wrote:
>>> z = [i + (2, -2)[i % 2] for i in range(10)]

>>
>> But then why would you want to use such feature? Wouldn't that make
>> the code much harder to understand then simply:
>>
>> z=[]
>> for i in range(10):
>> if i%2:
>> z.append(i-2)
>> else:
>> z.append(i+2)
>>
>> Or are we trying to write a book on "Puzzles in Python"?

>
> Once you get used to list comprehensions (and it doesn't take long),
> they are a more concise and compact way to express these operations.

After looking the two suggestions over a couple of times, I'm still
undecided as to which one is more readable for me. The problem is not
the list comprehensions (which I love and use extensively). The problem
is the odd syntax that has to be used for an if/then/else expression in
Python. I think I would have less trouble reading something like:

z = [i + (if i % 2 then -2 else 2) for i in range(10)]

but, of course, adding a if/then/else expression to Python is unlikely
to ever happen -- see the rejected PEP 308[1].

Steve

[1] http://www.python.org/peps/pep-0308.html

Nick Coghlan
Guest
Posts: n/a

 01-11-2005
Dan Bishop wrote:
> Luis M. Gonzalez wrote:
>
>>Hi there,
>>
>>I'd like to know if there is a way to add and else condition into a
>>list comprehension. I'm sure that I read somewhere an easy way to do
>>it, but I forgot it and now I can't find it...
>>
>>for example:
>>z=[i+2 for i in range(10) if i%2==0]
>>what if I want i [sic] to be "i-2" if i%2 is not equal to 0?

>
>
> z = [i + (2, -2)[i % 2] for i in range(10)]

For the specific case of +/- a number, (-1) ** x works, too:

z = [i + 2 * ((-1) ** i) for i in range(10)]

Not that I'm claiming it's particularly readable or anything. . . just that it
works

Cheers,
Nick.

--
Nick Coghlan | http://www.velocityreviews.com/forums/(E-Mail Removed) | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net