我有一些变量,我想选择第一个评估为True的变量,否则返回一个默认值。
例如,我有a
,b
和c
。我现有的代码:
result = a if a else (b if b else (c if c else default))
我正在考虑的另一种方法:
result = ([v for v in (a, b, c) if v] + [default])[0]
但他们都感到凌乱,那么有更多的Pythonic方式吗?
答案 0 :(得分:21)
您的意思是返回bool(value)==True
的第一个值吗?然后你可以依靠boolean operators return last evaluated argument:
result = a or b or c or default
答案 1 :(得分:17)
如果一个变量未“定义”,则无法访问其名称。因此,对'a'的任何引用都会引发NameError异常。
另一方面,如果你有类似的东西:
a = None
b = None
c = 3
你可以做到
default = 1
r = a or b or c or default
# r value is 3
答案 2 :(得分:5)
只要default
评估为True:
result = next((x for x in (a, b, c, d , e, default) if x))
答案 3 :(得分:2)
你可以做这样的事情(与其他答案相比,这是一个解决方案,你没有 将'缺失'值定义为None
或{ {1}}):
False
为了避免在未定义a,b或c时出现NameErrors:给函数一个字符串列表而不是变量引用(不能传递不存在的引用)。如果使用'globals()'范围之外的变量,可以使用getattr及其默认参数。
-
如果定义了a,b和c,我会选择这样的事情(考虑到空字符串,None或False评估为布尔值b = 6
c = 8
def first_defined(items):
for x in items:
try:
return globals()[x]
break
except KeyError:
continue
print first_defined(["a", "b", "c"])
):
False
答案 4 :(得分:1)
不知道这是否适用于所有情况,但这适用于这种情况。
a = False
b = "b"
c = False
default = "default"
print a or b or c or default # b
答案 5 :(得分:1)
这个怎么样?
a=None
b=None
c=None
val= reduce(lambda x,y:x or y,(a,b,c,"default"))
print val
以上打印"default"
。如果定义了任何输入,val
将包含第一个定义的输入。
答案 6 :(得分:1)
如果defined
表示ever assigned any value whatsoever to in any scope accessible from here
,则尝试访问“未定义”变量将引发NameError异常(或其某些子类,但捕获NameError也会捕获子类)。因此,从字面上看,执行绝对奇怪的任务的最简单方法是:
for varname in ('a', 'b', 'c'):
try: return eval(varname)
except NameError: pass
return default
任何缺少try / except的所谓解决方案都不会在“已定义”的上述含义下工作。基于探索特定范围的方法要么会错过其他范围,要么通过尝试复制eval
为您做的范围排序逻辑而非常复杂。
如果通过“已定义”,您实际上意味着“分配了一个评估为真的值(而不是假)”,即所有值实际上都是已定义(但可能恰好是假的,并且你想要第一个真正的价值),那么已经提出的a or b or c or default
就成了最简单的方法。但这对于“已定义”这个词来说是完全不同的(甚至是更奇怪的!)意思! - )