Unexpected replacement of zero in Python list comprehension

441 views Asked by At

I was looking at a stackoverflow question (if else in a list comprehension) and decided to try the following line

[ a if a else "Exception" for a in range(10) ],

and got the following list

[ "Exception", 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

as an output. I had expected the output to be

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

because zero is itself, just as the other numbers were evaluated. Thinking to test whether the behavior was affecting only the first index, I tried

[ a if a else "Exception" for a in range( 1, 10 ) ]

which outputed

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

and was what I would have not expected if the behavior was specific to the first index. Given the results so far, I tried the following thinking there was something particular about 0 being in the iterable.

[ a if a else "Exception" for a in [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]

and

import numpy [ a if a else "Exception" for a in numpy.zeros(10) ]

which resulted in the following for both cases

[ "Exception", "Exception", "Exception", "Exception", "Exception", "Exception", "Exception", "Exception", "Exception", "Exception" ]

If someone could explain this behavior to me, I would appreciate it. It appears that 0 being in the iterable could be triggering the unexpected behavior, but I am not confident on that conclusion.

3

There are 3 answers

1
Loocid On BEST ANSWER

Python treats 0 as false and any other number as true.

Try it for yourself:

if 0: print("0 is false")
if 1: print("1 is true")
if 2: print("2 is true")

The output you get is:

1 is true

2 is true

What your list compression is saying is:

"For each number from 0 to 9, if a is true, add a to the list, if a is false, add "Exception" to the list"

Because 0 is treated as False you get "Exception" for 0, then 1 2 3... etc for all the other numbers.

0
AudioBubble On

It is because 0 evaluates to False in python. All the other numbers would evaluate to True and thus be placed in the list.

Lets take a look at this.

[ a if a else "Exception" for a in range(10) ]

range(10) evaluates to 0,1,2,3,4,5,6,7,8,9

0 -> False

All other numbers -> True

1
Iron Fist On

0 is among the numeric type treated as False, same as [] Empty List and many others, so in your expression in list compression, the 0 is a False condition leading to the result of Exception string

You can check it with IDLE:

>>> bool(0)
False
>>> bool(1)
True
>>> bool([])
False
>>> bool([1,2])
True