2012-04-17 44 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