In each expression, only the last number is checked against the range
. The previous ones are evaluated "as is". In python, the expression if i:
evaluates to True if i
is not 0.
The value returned from the expressions (boolean or int) depends on what the conditions are. If you leave just 1 and 2
for example, the result will be the last int. However, since you have the v in range(n)
expression, which returns True
or False
, the result is cast into a boolean value.
Now, due to short-circuit evaluation, in the last case, only the zero gets evaluated. So the result is not cast into a boolean and 0 is returned.
Edit: After reading the comments, it becomes clear that you want to check if k
number exist in range(n)
. For that, you cannot use the simple expressions you've shown. You need to check if every individual value exists in the range. One - inefficient - approach would be this
if all([v in range(n) for v in values]):
print("All values exist in the range")
Edit 2 (by @Pranav Hosangadi)
Side note:
Since the all()
function takes generator expressions, you can avoid the list-comprehension altogether. When you do this, the generator expression will only calculate as many items as needed for the all()
to short-circuit. On the other hand, the list-comprehension approach will calculate all elements in the list, and then run all()
on that list. Here's a simple example:
l = [100] * 10000
l[-1] = 0
def f1(): # Using generator
return all(li == 0 for li in l)
def f2(): # Using list comp
return all([li == 0 for li in l])
Now for the generator-expression approach, all()
needs to calculate only the first element to know that it will short-circuit to False
. However, the list-comprehension approach calculates all elements of the list first. All but the last element of this list are False
. Then, all()
takes this list and short-circuits at the first element. Running some timing on these functions:
import timeit
timeit.timeit('f1()', setup='from __main__ import f1, l', number=10000)
# Out: 0.006381300001521595
timeit.timeit('f2()', setup='from __main__ import f2, l', number=10000)
# Out: 5.257489699986763
f1()
is significantly faster than f2()
.