2012-04-17 65 views
5

我有以下形式的表:將錶轉換爲分層字典?

A1, B1, C1, (value) 
A1, B1, C1, (value) 
A1, B1, C2, (value) 
A1, B2, C1, (value) 
A1, B2, C1, (value) 
A1, B2, C2, (value) 
A1, B2, C2, (value) 
A2, B1, C1, (value) 
A2, B1, C1, (value) 
A2, B1, C2, (value) 
A2, B1, C2, (value) 
A2, B2, C1, (value) 
A2, B2, C1, (value) 
A2, B2, C2, (value) 
A2, B2, C2, (value) 

我想在python與它的工作作爲一個字典,形式:

H = { 
    'A1':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    }, 
    'A2':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    } 
} 

這樣H[A][B][C]產生的一個特定的唯一列表值。對於小型字典,我可能只是像上面那樣定義結構,但我正在尋找一種有效的方法來遍歷表並構建字典,而不必提前指定字典鍵。

+5

您是否總是查找A,B,C值的三倍?如果是這樣,你最好用一個'dict'使用這些三元組作爲關鍵字。 – 2012-04-17 14:34:29

回答

8
input = [('A1', 'B1', 'C1', 'Value'), (...)] 

from collections import defaultdict 

tree = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 
#Alternatively you could use partial() rather than lambda: 
#tree = defaultdict(partial(defaultdict, partial(defaultdict, list))) 

for x, y, z, value in input: 
    tree[x][y][z].append(value) 
+1

請注意,如果table是一個文本文件,您需要像open一樣使用''table「作爲文件:'''input = [line.split()for line in file]''。 – 2012-04-17 14:40:19

+2

這裏使用lambdas的另一種方法是使用''functools.partial()'':''tree = defaultdict(partial(defaultdict,partial(defaultdict,list)))'' - 我覺得這個更清楚,但那可能只是做我自己。 – 2012-04-17 14:43:19

+0

@Lattyware有趣的,謝謝你。 – 2012-04-17 14:45:22

2
d = {} 
for (a, b, c, value) in your_table_of_tuples: 
    d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value) 
+0

爲什麼在''defaultdict''上使用''setdefault()''? – 2012-04-17 14:38:08

+0

@Lattyware:爲什麼不呢? – vartec 2012-04-17 14:41:01

+0

當你使用它時,我會爭辯說它更加醜陋。 – 2012-04-17 14:46:01

4

如果你只訪問H [A] [B] [C](也就是,從來沒有H [A]奧德H [A] [B]單獨的),我建議一個IMO清潔解決方案:使用元組作爲默認值索引:

from collections import defaultdict 
h = defaultdict(list) 
for a, b, c, value in input: 
    h[a, b, c].append(value) 
+0

這也是一個非常有效的(優雅的)解決方案,雖然它確實需要他不想單獨訪問子字典。 (編輯刪除一些額外的縮進,不需要的括號和PEP-8變量名稱)。 – 2012-04-17 14:49:27

+0

感謝您發佈此解決方案。在這種情況下,我需要訪問子字典,但我沒有在問題中指定。如果這種情況在將來存在,這將非常優雅。 – 2012-04-17 14:58:35