2012-10-18 34 views
3

我的字典子類,他們的工作是動態添加嵌套的字典鍵,如果不存在的話,做清單追加,如果追加被稱爲列表:Python的 - 附加到嵌套在字典子

class PowerDict(dict): 
    def __getitem__(self, item): 
     try: 
      return dict.__getitem__(self, item) 
     except KeyError: 
      value = self[item] = type(self)() 
      return value 
    def append(self,item): 
     if type(self) != list: 
      self = list() 
      self.append(item) 

所以

a = PowerDict() 
a['1']['2'] = 3 

產生輸出:

a = {'1': {'2': 3}} 

但是,有時我需要做這樣的事情:

b = PowerDict() 
b['1']['2'].append(3) 
b['1']['2'].append(4) 

應該產生的輸出:

b = {'1': {'2': [3, 4]}} 

但上面的代碼產生輸出:

{'1': {'2': {}}} 

什麼,我缺少什麼?

+3

你不能說'self = list()'...你需要設置鍵等於一個列表... self是一個字典 –

+3

確實,'self = list()'只是重新綁定變量'self'。 –

+1

您是否附加到多重索引格式?我發現一個由元組索引的dictonary更加優雅:'a [1,2] = 3'。 – katrielalex

回答

1
class PowerDict(dict): 
    # http://stackoverflow.com/a/3405143/190597 (gnibbler) 
    def __init__(self, parent = None, key = None): 
     self.parent = parent 
     self.key = key 
    def __missing__(self, key): 
     self[key] = PowerDict(self, key) 
     return self[key] 
    def append(self, item): 
     self.parent[self.key] = [item] 
    def __setitem__(self, key, val): 
     dict.__setitem__(self, key, val) 
     try: 
      val.parent = self 
      val.key = key 
     except AttributeError: 
      pass 

a = PowerDict() 
a['1']['2'] = 3 
print(a) 

b = PowerDict() 
b['1']['2'].append(3) 
b['1']['2'].append(4) 
print(b) 

a['1']['2'] = b 
a['1']['2'].append(5) 
print(a['1']['2']) 

產生

{'1': {'2': 3}} 
{'1': {'2': [3, 4]}} 
[5] 
+0

你拯救了我的一天! – user1756095

+0

@unutbu我**強烈**不同意這樣的想法。當「遍歷」這樣的「權威」時,你永遠不會知道你將使用哪種類型(除非你會使用「isinstance」,通常認爲這不是一個好習慣)。你怎麼知道如何處理你從字典中獲取的值? –

+1

有理由不喜歡'PowerDict' - 特別是'__setitem__'的潛在bugginess。但遍歷不是'PowerDict'唯一的問題。您的異議同樣適用於簡單的嵌套字典:'{'1':{'2':[3,4],...}}'。我想在這篇文章中展示的是,它有可能實現一個具有所需語法糖的對象。可取性問題取決於上下文。這僅僅是爲了學習還是爲了生產代碼?由於OP沒有說明,我沒有建議。 – unutbu

0

你的append()方法永遠不會工作。通過做self = list(),您只需將名稱self重新分配給一個新列表,然後將其丟棄。

我不明白你在做什麼 - 從getitem,你正在創建新的字典,如果有什麼缺失的話......你如何混合列表行爲?

0

你的問題之一是重新分配自己,但是,那不是。嘗試在append命令中輸出self的值,您可以看到另一個問題:循環進入無限遞歸。這是因爲你在append命令中的powerDict上調用append命令!

這應該解決您的問題,而無需重新編寫附加命令,但我強烈建議你也無妨重新編寫,以避免上述問題:

b['1']['2']= [3] 
b['1']['2'].append(4)