2012-12-03 20 views
4

有沒有一種方法可以在字典中執行三元操作,其中測試是has_key()而不會觸及關鍵錯誤?即字典上的三元操作

variable = dict["the_key"] if dict.has_key("the_key") else "something" 

(這擊中明顯的關鍵錯誤)

做不到這一點,什麼是分配基礎上,可能會或可能不會有問題的密鑰的字典一堆變量值的最Python的方式?重複:

if dict.has_key('key'): 
    value = dict['key'] 
else: 
    value = "value" 

廣告似乎很不雅觀。

+1

您需要學習查看python庫文檔。 – Marcin

+1

你的例子不應該引發KeyError。三元運算符只評估其中一個結果。 – BrenBarn

+0

在d'中使用''the_key'而不是'd.has_key('the_key')'。後者在Python 3中不存在。 – argentpepper

回答

5

約亨Ritzel的答案是做的這個時間99.9999%的正確方法:當他注意到

variable = d.get("the key", "something") 

,它不會讓你短路默認的評價值。你通常不在乎。它的默認值是"something",你當然不會。只有在默認值是危險的或非常昂貴的情況下才會產生。

只有在這種情況下,您才能也應該使用您的想法。除非你想in,而不是has_key(因爲它更具可讀性,更快,並不會被棄用):

variable = d["the key"] if "the key" in d else expensiveComputation() 

但是,它可能是值得使用的if語句而不是三元的表現,因爲事實上,你」再避免expensiveComputation是重要的,你希望它是更明顯:

if "the_key" in d: 
    variable = d["the key"] 
else: 
    variable = expensiveComputation() 

如果你希望默認情況下是罕見的,這是更好的:

try: 
    variable = d["the key"] 
except KeyError: 
    variable = expensiveComputation() 

如果由於某種原因,你需要避免在尋找鑰匙了兩次,你也可以不處理異常,則需要短路默認,一次全部:

sentinel = object() 
variable = d.get(sentinel) 
if variable == sentinel: 
    variable = expensiveComputation() 

而且是的,你可以把所有東西都包裝在一個函數中,這樣它就是一條線,但是你幾乎肯定不想隱藏你一次做三件稀有事情的事實。

或者,當然,你可以只讓做:

d = collections.defaultdict(expensiveComputation) 

然後,它只是:

variable = d["the key"] 

這有設置d["the key"]expensiveComputation()的副作用將其返回到前你,所以稍後致電d["the key"]將返回相同的值。如果這聽起來合適,這是最好的答案;如果你永遠不會使用相同的密鑰兩次,或者這些事情是巨大而浪費的以保持等等,這是一個壞主意。

,或者,你可以重寫dict.__missing__方法,而不是使用defaultdict

class MyDict(dict): 
    def __missing__(self, key): 
     return expensiveComputation() 

然後,再次,它只是:

variable = d["the key"] 

這個人是合適的,當你想生成價值每次分開,並且不保留它在以後。

+1

如果您需要密鑰來執行昂貴的計算,您可以使用替代'__missing__'而不是'defaultdict'的'dict'子類。 – kindall

+0

好點,@ kindall;我會更新答案。 – abarnert

10

此:

mydict.get(key, default_value) 

沒有100%相同default_value被立刻而當條件滿足時else部件僅評價進行評價。

0
value = 'value' 
if 'key' in dict: 
    value = dict['key'] 

或定義默認值

dict.get( '鍵', '值')

1

variable = d['the_key'] if 'the_key' in d else 'something'

+0

由於許多原因,這是正確的/最好的答案:它是OP所要求的三元表達式;它使用'in'運算符而不是已棄用的'has_key';並且它不會評估else子句,除非在dict中不存在該鍵。 – PaulMcG