2013-10-04 46 views
58

有沒有辦法讓defaultdict也是defaultdict的默認值? IOW,如果我這樣做:defaultdict defaultdict,嵌套

x = defaultdict(...stuff...) 
x[0][1][0] 
{} 

這就是我想要的。我可能會最終使用一堆模式,但是當我意識到我不知道如何做到這一點時,它讓我感興趣。

所以,我可以這樣做:

x = defaultdict(defaultdict) 

但這只是一層:

x[0] 
{} 
x[0][0] 
KeyError: 0 

有食譜,可以做到這一點。但是可以簡單地使用正常的defaultdict參數來完成嗎?

請注意,有人將此標記爲Python: defaultdict of defaultdict?的副本,但這不是同一個問題......該問題是如何執行兩級defaultdict;這一個是如何做一個無限級遞歸defaultdict。

+0

的可能的複製[Python的:defaultdict的defaultdict(http://stackoverflow.com/questions/5029934/python-defaultdict-of-defaultdict) – malioboro

+0

不是真的......在問題中添加了信息來說明原因。雖然這是一個有用的問題。 –

回答

88

對於級別爲任意數量的:

def rec_dd(): 
    return defaultdict(rec_dd) 

>>> x = rec_dd() 
>>> x['a']['b']['c']['d'] 
defaultdict(<function rec_dd at 0x7f0dcef81500>, {}) 
>>> print json.dumps(x) 
{"a": {"b": {"c": {"d": {}}}}} 

當然,你也可以做到這一點是lambda,但我發現lambda表達式要少可讀性。在任何情況下,它應該是這樣的:

rec_dd = lambda: defaultdict(rec_dd) 
+1

的確是一個完美的例子,謝謝。你可以把它擴展到這種情況,數據從json加載到defaultdict的defaultdict中嗎? –

+0

一個音符。如果你正在嘗試使用這段代碼,酸洗'lambda'將不起作用。 –

25

有做一個漂亮的把戲:

tree = lambda: defaultdict(tree) 

然後你就可以創建你xx = tree()

17

到BrenBarn的解決方案類似,但不包含變量tree名的兩倍,因此它甚至改變變量字典後作品:

tree = (lambda f: f(f))(lambda a: (lambda: defaultdict(a(a)))) 

然後您可以創建每個新xx = tree()


對於def版本,我們可以使用函數閉範圍,以保護數據結構從那裏現有的情況下停止工作,如果該tree名稱是反彈的缺陷。它看起來像這樣:

from collections import defaultdict 

def tree(): 
    def the_tree(): 
     return defaultdict(the_tree) 
    return the_tree() 
+4

我必須考慮這一點(這有點複雜)。但我認爲你的觀點是,如果做x = tree(),但是稍後有人來,並且tree = None,那麼這個仍然可以工作,那不會? –

+3

正確,那是我的觀點。 – pts

75

其他的答案在這裏告訴你如何創建一個defaultdict其中包含「無限多」 defaultdict,但他們未能解決什麼,我認爲可能是您最初的需求這是簡單地有一個雙深度的defaultdict。

你可能一直在尋找:

defaultdict(lambda: defaultdict(dict)) 

爲什麼你可能更喜歡這種結構的原因是:

  • 它比遞歸解決方案更加明確,因此可能更容易理解的讀者。
  • 這使得該defaultdict的「葉」比一本字典以外的東西,比如,:defaultdict(lambda: defaultdict(list))defaultdict(lambda: defaultdict(set))
+2

defaultdict(lambda:defaultdict(list))正確的形式? –

+0

Ooops,是的,'lambda'形式是正確的 - 因爲'defaultdict(something)'返回一個類似字典的對象,但'defaultdict'需要一個可調用的對象!謝謝! –

+0

這被標記爲另一個問題的可能重複......但這不是我的原始問題。我知道如何創建一個兩級defaultdict;我不知道如何使它遞歸。這個答案實際上類似於http://stackoverflow.com/questions/5029934/python-defaultdict-of-defaultdict –