(注意:以下情况只是示例性的。这个问题适用于任何可以评估为bool的事情)
如果用户未提供自定义列表,则应使用默认列表:
default_list = ...
custom_list = ...
if custom_list:
list = custom_list
else:
list = default_list
您可以将其缩短为:
default_list = ...
custom_list = ...
list = custom_list if custom_list else default_list
现在,根据https://docs.python.org/2.7/reference/expressions.html#or ...
表达式
x or y
首先评估x
;如果 x true ,则返回其值;否则,将评估 y 并返回结果值。
...,or
不返回布尔值,而是返回布尔转换不为false的第一个值。因此,以下是有效的代码:
list = custom_list or default_list
这类似于C#Null Coalescing Operator,除了它应该在Python中作为 False Coalescing Operator 重新定义,它返回第一个非假的参数。
最后一个例子似乎更容易阅读,但是它被认为是pythonic吗?
pep8 (程序)和 pylint 都不会抱怨。
答案 0 :(得分:4)
这完全有效,你可以使用它。即使documentation of or
也有相同的例子。
请注意,它们既不返回也不限制它们返回
False
和True
的值和类型,而是返回最后一个已计算的参数。 这有时很有用,例如,如果s
是一个字符串,如果它是空的,则应该用默认值替换,表达式s or 'foo'
会产生所需的值。
但是,or
方法有局限性。如果你想故意允许一个非Truthy值,那么它 就不可能。
我们假设您要允许空列表
my_list = [] or default_list
将始终提供default_list
。例如,
print [] or [1, 2, 3]
# [1, 2, 3]
但是使用条件表达式我们可以像这样处理它
custom_list if isinstance(custom_list, list) else default_list
删除旧文档,引用BDFL's FAQ,
4.16。问:是否有相当于C的“?:”三元运算符?
一个。不是直接的。在许多情况下,您可以使用
Steve Majewski(或蒂姆·彼得斯?)建议如下 解决方案:a?b:c
模仿a and b or c
,但有一个缺陷:如果b
为零(或空,或None
- 任何内容 测试错误)然后将选择c。在很多情况下你 可以通过查看代码来证明这不可能发生(例如因为 b是常数或具有永远不会是假的类型,但总的来说 这可能是个问题。(a and [b] or [c])[0]
。因为[b]
是一个单例列表 永远不会是假的,所以永远不会采取错误的道路;然后将[0]
应用于 整个事情得到你真正想要的b或c。丑,但它 在极少数情况下让你到达那里真的很不方便 使用'if'重写代码。
答案 1 :(得分:4)
是的,在将条件表达式构造添加到语言之前,使用or
使其短路属性成为常态。
使用时,现在仍然是完全pythonic:
foo = bar or baz
如果bar
为false-y(在布尔上下文中计算结果为false),则回退到默认值。短路这一事实也可以让你做到这样的事情:
foo = bar or expensive_calculation(baz) # only if bar is false-y
如果expensive_calculation()
是true-y(在布尔上下文中求值为true),则不执行bar
。同样,您可以使用and
来确保满足前提条件:
foo = bar and bar(baz) # call `bar()` only if it is truth-y
你应使用条件表达式:
foo = bar and spam or eggs
但是。这是条件表达式旨在取代的内容。我的想法是,如果bar
是真实的,则选择spam
,否则选择eggs
。但如果spam
是假的,那就会崩溃!这是一个常见的错误来源,而
foo = spam if bar else eggs
如果spam
是真实的,总是选择bar
。