Python:循环和嵌套字典

时间:2018-02-02 19:16:41

标签: python python-3.x loops dictionary hash

我有3个元组:

o = (0, 1)
n = ((1, 2), (1,))
c = ((30, 70), (20,))

我想放入嵌套字典。所需的输出是:

{'0':{'1':30, '2':70}, '1':{'1':20}}

我尝试了以下内容:

for x in enumerate(o):
    graph[str(o[x])] = {}
    for y in enumerate(n):
        for z in enumerate(y):
            graph[str(o[x])][n[x][z]] = c[x][z]

哪个不起作用,我不知道如何继续。

1 个答案:

答案 0 :(得分:0)

(1)(20)不是元组(由评论中的Ilja Everilä指出),这是一个问题。由于它们实际上是int类型,因此您无法对它们进行迭代或使用[]进行索引。

首先关于enumerate()的一个注释,你使用不当。此函数返回(index, value)的元组。更多信息here

如果无法更改源数据,您可以稍微修改一下代码以获得所需的结果。像以前一样遍历元组,但使用isinstance检查元素是否为int

graph = {}
for i, x in enumerate(o):
    graph[x] = {}
    if isinstance(n[i], int):
        graph[x][n[i]] = c[i]
    else:
        for j in range(len(n[i])):
            graph[x][n[i][j]] = c[i][j]
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}

使用zip()

可以进一步简化此代码的else
graph = {}
for i, x in enumerate(o):
    graph[x] = {}
    if isinstance(n[i], int):
        graph[x][n[i]] = c[i]
    else:
        for y, z in zip(n[i], c[i]):
            graph[x][y] = z
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}

但是,更好的解决方案是将源数据nc更改为仅包含元组:

def make_tuple(x):
    return x if isinstance(x, tuple) else (x, )

new_n = map(make_tuple, n)
new_c = map(make_tuple, c)

然后上面的代码不再需要isinstance()检查,可以简化为:

graph = {}
for i, x in enumerate(o):
    graph[x] = {}
    for y, z in zip(new_n[i], new_c[i]):
        graph[x][y] = z
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}

我们可以进一步简化为:

graph = {}
for ko, N, C in zip(o, new_n, new_c):
    graph[ko] = {}
    for kn, vc in zip(N, C):
        graph[ko][kn] = vc
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}

或者如果是紧凑的一个班轮(直接翻译上面的代码块到dict理解):

graph = {ko: {kn:vc for kn, vc in zip(N, C)} for ko, N, C in zip(o, new_n, new_c)}
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}