我有一些代码:
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)
我把它重写为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)
我发现在第一个代码段中我不能遗漏else 0
而第二个示例不能包含else 0
。
这些例子之间有什么区别else 0
?
答案 0 :(得分:4)
这里有两件非常不同的东西。
在第一个表达式中,您使用conditional expression来生成值;这需要else
因为表达式总是需要生成某些东西。
例如,如果你写了:
sum += each if each >= part[0] and each <= part[1] # removing "else 0"
那么,如果测试结果为假,那么会添加到总和中?
在第二个中,您有一个generator expression,if
是可能部分(称为comp_if
in the grammar)的一部分,在(嵌套)for
循环旁边。与if ...:
语句类似,它会过滤使用序列中的哪些元素,并且不需要在 false 情况下生成值;你不会以其他方式过滤。
将它带回你的榜样:
sum(x for x in data if low<=x<=high)
当if
测试为假时,x
只是从循环中省略而不是求和。你在第一个例子中做了同样的事情:
if each >= part[0] and each <= part[1]:
# only add to `sum` if true
sum += each
答案 1 :(得分:1)
这根本不是同一种语法。第一个是三元运算符(如C)中的(a?b:c)。在这里没有else子句是没有任何意义的。第二个是列表推导,if子句的目的是过滤迭代的元素。
答案 2 :(得分:1)
x if y else z
这是一个返回值的inline-if表达式。它必须始终返回一个值,它不能返回值,因此它必须包含else
子句。
[x for x in y if z]
这是列表理解。这里的if
充当循环的过滤器。它相当于for x in y: if z: ...
。
要在其中添加else
,请将inline-if表达式替换为x
:
[x if y else z for foo in bar]