我有一些變量,我想選擇第一個評估爲True,否則返回一個默認值。Pythonic的方式來選擇第一個變量評估爲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]
但他們都覺得凌亂,所以有一個更Python的方式?
我有一些變量,我想選擇第一個評估爲True,否則返回一個默認值。Pythonic的方式來選擇第一個變量評估爲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]
但他們都覺得凌亂,所以有一個更Python的方式?
您的意思是返回第一個值bool(value)==True
?然後,你可以依靠的事實是boolean operators return last evaluated argument:
result = a or b or c or default
NB(對於OP)空字符串('「」')具有false布爾值('bool(「」)== False');請記住,如果你不認爲它在程序中是「假」的話。同樣適用於'()'(空元組),'{}'(空字典),'[]'(空列表)和零(任何數字類型)。 – tzot 2010-02-01 20:05:25
如果一個變量沒有被「定義」,則無法訪問它的名字。所以任何對'a'的引用都會引發NameError異常。
在另一方面,如果你有這樣的:
a = None
b = None
c = 3
你可以做
default = 1
r = a or b or c or default
# r value is 3
asker提供的兩個選項中沒有一個運行到同一個NameErrorException中? – donut 2009-11-26 12:34:37
沒錯。在分配內容之前,您無法讀取變量。 – 2009-11-26 12:44:02
不知道,如果這個工程在任何情況下,但是這適用於這種情況。
a = False
b = "b"
c = False
default = "default"
print a or b or c or default # b
這個怎麼樣?
a=None
b=None
c=None
val= reduce(lambda x,y:x or y,(a,b,c,"default"))
print val
以上打印"default"
。如果定義了任何輸入,則val
將包含第一個定義的輸入。
只要default
評估爲真:
result = next((x for x in (a, b, c, d , e, default) if x))
如果你已經決定使用'next',你可以使用它的'default'參數 – abyx 2009-11-26 12:55:22
你可以做這樣的事情(相對於其他答案這是你不有定義解決方案的「缺失」值爲是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"])
爲了避免NameErrors a,b或c爲沒有定義時:給出的函數字符串的列表,而不是可變的引用(你不能傳遞不存在的引用)。如果您在'globals()'作用域之外使用變量,則可以使用getattr及其默認參數。
-
如果A,B和C的定義,我會去這樣的事情(在考慮到一個空字符串,無或虛假評估爲布爾False
):
a = None
b = 6
c = 8
def firstitem(items):
for x in items:
if x:
return x
break
else:
continue
print firstitem([a, b, c])
返回後你不需要'break':你已經不在循環中。在循環結束時,您也不需要「else:continue」:無論如何,這將會發生。 – 2010-01-31 20:48:00
如果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 /除了上述意義下是行不通的「定義」。基於探索特定範圍的方法可能會錯過其他範圍,或者通過嘗試複製eval
爲您做的範圍排序邏輯非常複雜。
如果通過「定義」你實際上是指「賦值爲真值(而不是假)」,即所有值實際上是定義爲(但可能碰巧是錯誤的,而你想要第一個真正的價值),那麼已經提出的a or b or c or default
成爲最簡單的方法。但是,這是一個完全不同的(甚至更we!)意思是「定義」! - )
我不知道「pythonic」,但我喜歡第一個。尼斯和好聽,易於閱讀:) – mtvee 2009-11-26 12:10:10
你是什麼意思「定義」?例如,如果b未定義,那麼您將得到一個NameError。你的代碼檢查變量是否被定義,但是爲空/零/假。 – 2009-11-26 12:15:18
請注意,在Python中,您不需要定義變量,而是將名稱綁定到對象。 – 2009-11-26 12:20:44