2012-08-15 95 views
2

這些方法之間有什麼區別,缺陷或缺點嗎?Python字典,關鍵存在與回退

foo = dict(key=u"") 
bar = foo.get('key', 'foobar') 

VS

foo = dict(key=u"") 
bar = bool(foo['key']) or 'foobar' 
+1

第二個引發錯誤?它實際上不會倒退 – jamylak 2012-08-15 14:59:42

+0

第一個是正確的,第二個不是? – 2012-08-15 15:00:40

+0

沒有它肯定不 – 2012-08-15 15:00:42

回答

6

你應該最肯定不會使用第二種形式,因爲如果密鑰不存在您的字典,它會拋出KeyError。你只能從第二種形式中獲得可接受的行爲,因爲密鑰已設置。

+0

*和* OP得到一個布爾值而不是'foo ['key']'的值.. – 2012-08-15 15:06:21

3

第二個例子將提高KeyError如果foo['key']不存在。

如果你想爲默認值,如果foo['key']不存在或包含falsey值賦給bar,這將是Python的方式做到這一點:

bar = foo.get('key') or 'foobar' 
+0

我不會使用'或'。例如,考慮'foo = dict(key = None)'的情況。 – 2012-08-15 15:02:48

+0

我明白你的觀點,只有當不存在的'foo ['key']'和'None' /其他falsey值對用戶意味着同樣的事情時,我的示例纔有效。 – Imran 2012-08-15 15:04:32

4

代碼的第一片嘗試從fookey相關聯的值,並且如果foo不具有鍵key,默認爲foobar。因此,這裏有兩種情況:

  1. foo有鑰匙key,所以bar設置爲foo[key]
  2. foo沒有關鍵key,所以bar設置爲"foobar"

第二查看與foo中的密鑰key相關聯的值,如果該值是虛假的(即,如果是bool(foo[key])==False),則默認爲foobar。如果foo沒有密鑰key,則會產生KeyError。因此,有案件這裏:

  1. foo有鑰匙key,並bool(foo[key])==True,所以bar設置爲True
  2. foo有鑰匙key,並bool(foo[key])==False,所以bar設置爲"foobar"
  3. foo沒有鑰匙key,所以代碼提了一個KeyError
1

這是使用bool()

one = {"my_key": None} 

print "Get:", one.get("my_key") 
print "Bool:", bool(one.get("my_key")) 
print "Get with falback:", one.get("my_key", "other") 

Get: None 
Bool: False 
Get with falback: None 

注意,書中有一個值,None問題,但布爾計算結果爲false。你應該使用get("key", "default"),它的目的是爲了完成這項工作。

+0

OP的示例已經公開了這種行爲,一個空字符串是虛假的。 – 2012-08-15 15:04:26

+0

事實上,我的回答表明他們是不同的。除非我誤解了它? – Joe 2012-08-15 15:07:00

+0

不,我只是想指出問題已經出現在OP的例子中,就這些。 – 2012-08-15 15:10:45

1

如果你認爲foo = dict(key=u"")會產生一個字典,那麼默認值是一個空字符串,你就錯了。你需要爲一個defaultdict

In [6]: bool(foo['key']) or 'foobar' 
Out[6]: 'foobar' 
In [7]: foo = dict(key='') 
In [9]: bool(foo['nokey']) or 'foobar' 
KeyError: 'nokey' 

要麼使用defaultdict,或dict.get,甚至dict.setdefault

好所有的工作方式太:

In [10]: try: 
    ....:  v = foo['nokey'] 
    ....: except KeyError: 
    ....:  v = 'foobar' 
    ....:  

In [11]: v 
Out[11]: 'foobar' 
0

是:

foo.get('key', 'foobar')始終返回的東西(如果有一個鍵名「鍵」,它會返回它的值,如果沒有這樣的鍵,也可以返回「foobar的」。

bool(foo['key']) or 'foobar'可以提高一個KeyError如果有一個名爲「鑰匙」沒有這樣的關鍵。

此外 - 這裏使用or並不是指示性的,所以get方法更可取。