Reputation: 927
I have some code:
a_part = [2001, 12000]
b_part = [1001, 2000]
c_part = [11, 1000]
d_part = [1, 10]
data = range(1, 12000)
labels = [a_part, b_part, c_part, d_part]
sizes = []
# ---
for part in labels:
sum = 0
for each in data:
sum += each if each >= part[0] and each <= part[1] else 0
# error
# sum += each if each >= part[0] and each <= part[1]
sizes.append(sum)
print(sizes)
And I rewrote this to be more Pythonic:
sizes = [sum(x for x in data if low<=x<=high) for low,high in labels]
# error
# sizes = [sum(x for x in data if low<=x<=high else 0) for low else 0,high in labels]
print(sizes)
I found that in the first snippet I can't leave out else 0
while the second example can't contain else 0
.
What is the difference else 0
makes between these examples?
Upvotes: 1
Views: 1185
Reputation: 1121914
You have two very different things here.
In the first you have an expression, and are using a conditional expression to produce the value; that requires an else
because an expression always needs to produce something.
For example, if you wrote:
sum += each if each >= part[0] and each <= part[1] # removing "else 0"
then what would be added to the sum if the test was false?
In the second you have a generator expression, and the if
is part of the possible parts (called comp_if
in the grammar), next to (nested) for
loops. Like an if ...:
statement, it filters what elements in the sequence are used, and that doesn't need to produce a value in the false case; you would not be filtering otherwise.
To bring that back to your example:
sum(x for x in data if low<=x<=high)
when the if
test is false, that x
is just omitted from the loop and not summed. You'd do the same thing in the first example with:
if each >= part[0] and each <= part[1]:
# only add to `sum` if true
sum += each
Upvotes: 4
Reputation: 522081
x if y else z
This is an inline-if expression which returns a value. It must always return a value, it cannot not return a value, hence it must contain an else
clause.
[x for x in y if z]
This is a list comprehension. The if
here acts as a filter for the loop. It's equivalent to for x in y: if z: ...
.
To have an else
in there, you put the inline-if expression in place of x
:
[x if y else z for foo in bar]
Upvotes: 1
Reputation: 856
This is not the same syntax at all. The first one is a ternary operator (like (a ? b : c) in C). It wouldn't make any sense not to have the else clause here. The second one is a list comprehension and the purpose of the if clause is to filter the elements of the iterable.
Upvotes: 1