Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unexpected result when using a list comprehension on a list of booleans Python

r=[True, False,True,False, False]
print([i for i in r if str(r[i])=="True"])

this code gives the following unexpected result: [False, False, False]

Why is this the behavior? I would expect: [True, True]

like image 363
Sheela Singla Avatar asked Dec 01 '22 10:12

Sheela Singla


2 Answers

i is a boolean with a value of True or False. If you use it as an index in r[i], you will get either r[0] or r[1] because bool is a subclass of int.

You can picture it as r[int(i)] and int(True) == 1, int(False) == 0.

What you probably mean is:

print([i for i in range(len(r)) if str(r[i])=="True"])

where i is an integer or:

print([i for i in r if str(i)=="True"])

where i is a boolean.

Note that if i is a boolean, there is little point in if str(i) == "True". A more concise way of writing it would be:

print([i for i in r if i])

or even using the filter built-in function:

it = filter(None, r)
print(list(it))
like image 196
Jacques Gaudin Avatar answered Dec 04 '22 00:12

Jacques Gaudin


You meant str(i).

With your original code,

  • on the first iteration, i is True, and as True has the integer value 1, r[i] will be r[1], which is False. The if condition fails.

  • on the second iteration, i is False, and as False has the integer value 0, r[i] will be r[0], which is True. The if condition succeeds and i (which is False) gets added to the result.

like image 39
Thierry Lathuille Avatar answered Dec 04 '22 00:12

Thierry Lathuille