【发布时间】:2015-07-17 20:56:47
【问题描述】:
我目前正在这样做:
if x in a and y in a and z in a and q in a and r in a and s in a:
print b
有没有更 Pythonic 的方式来表达这个if 语句?
【问题讨论】:
标签: python if-statement
我目前正在这样做:
if x in a and y in a and z in a and q in a and r in a and s in a:
print b
有没有更 Pythonic 的方式来表达这个if 语句?
【问题讨论】:
标签: python if-statement
使用all 函数可以以简洁紧凑的方式编写:
if all(i in a for i in (x, y, z, q, r, s)):
print b
即使对象不可散列或a 对象有一些有趣的__contains__ 方法,这段代码的作用也应该与您的示例几乎完全相同。 all 函数也具有与原始问题中and 的链相似的short-circuit 行为。在一个元组(或一个列表)中收集所有要测试的对象将保证测试的执行顺序与原始问题中的相同。如果你使用一套,顺序可能是随机的。
【讨论】:
all 是懒惰的。问题是元组(x, y, z, q, r, s) 是在运行任何迭代之前完全构建的,如果x、y 等是表达式,其中一些可能会引发异常。在这种情况下,OP 的代码可以返回 False 并避免异常,而此代码将始终引发异常。
__contains__ 方法”——所以我们到达了鸭式打字的棘手角落。提问者说“在可迭代中”,但如果 a 实现 __contains__ 那么对于提问者的代码,a 是否可迭代甚至都无关紧要......
.contains() 方法和一个 if_all 语句,这种事情会更好。我认为条件会更好地阅读为if all (a.__contains__(i) for i in [x, y, z, q, r, s]):,或者如果您更喜欢避免使用.__contains__,然后使用operator.contains:if all (contains(a, i) for i in [x, y, z, q, r, s]):
另一种方法是使用子集:
if {x, y, z, q, r, s}.issubset(a):
print(b)
REPL 示例:
>>> {0, 1, 2}.issubset([0, 1, 2, 3])
True
>>> {0, 1, 2}.issubset([1, 2, 3])
False
这种方法的一个注意事项是所有x、y、z 等都必须是可散列的。
【讨论】:
if all(v in a for v in {x, y, z, q, r, s}):
print(b)
【讨论】:
转换为集合,或者:
if len({x, y, z, q, r, s} - set(a)) == 0:
print b
或
t = {x, y, z, q, r, s}
if t & set(a) == t:
print b
【讨论】: