从元组创建嵌套字典

时间:2020-01-21 21:09:14

标签: python python-3.x dictionary

我正在尝试从元组创建嵌套字典。这个元组是这样排列的:

content=(p0,a0,b0,c0,d0,p1,a1,b1,c1,d1,....)

我正在尝试将其转换为看起来像这样的嵌套字典:

my_dictionary=[{"p":"p0","a":"a0","b":"b0","c":"c0","d":"d0"},
"p":"p1","a":"a1","b":"b1","c":"c1","d":"d1"},
"p":"p2","a":"a2","b":"b2","c":"c2","d":"d2"},
...]

键始终是相同的keys=[p,a,b,c,d]。我的问题是我不知道如何设置此循环以及如何格式化此循环以获取字典。

2 个答案:

答案 0 :(得分:1)

这是一个替代解决方案。基本上,您将在列表中逐块前进,并以此方式创建dict。这不是最短的方法,但对于开发人员来说可能更容易理解。

keys = ('p', 'a', 'b', 'c', 'd')
index = 0
key_len = len(keys)
content_len = len(content)

output = []
while index < content_len:
    # This grabs enough values in content from the current index to match the keys
    current_content = content[index:index + key_len]

    # This creates a structure [(keys[0], current_content[0]), (keys[1], ...
    # if current_content = [1,2,3,4,5] then zip will give us something close to
    # [('p', 1),('a', 2),('b', 3),('c', 4),('d', 5)] 
    matches = zip(keys, current_content)
    # Note on the above: based on your version of Python, the output of zip may change. 
    # (In Py3k, it creates a "zip object", in Python 2.x it creates a list)
    # That will not affect this loop.

    # A list of two-entry tuples can be passed as the parameter to the `dict` class.
    current_dict = dict(matches)

    # append the output
    output.append(current_dict)

    # Be sure to move forward in the list
    index += key_len

答案 1 :(得分:0)

我可以想到两种方式,基于对序列中元素进行分组的相同惯用方式:

import itertools as it


content = range(50)
keys = ('p', 'a', 'b', 'c', 'd')

dicts = [dict(zip(keys, gr)) for gr in zip(*[iter(content)]*len(keys))]
print(dicts)

dicts2 = [dict(pairs) for pairs in zip(*[iter(zip(it.cycle(keys), content))]*len(keys))]
print(dicts2)

产生

[{'p': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4}, {'p': 5, 'a': 6, 'b': 7, 'c': 8, 'd': 9}, {'p': 10, 'a': 11, 'b': 12, 'c': 13, 'd': 14}, {'p': 15, 'a': 16, 'b': 17, 'c': 18, 'd': 19}, {'p': 20, 'a': 21, 'b': 22, 'c': 23, 'd': 24}, {'p': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29}, {'p': 30, 'a': 31, 'b': 32, 'c': 33, 'd': 34}, {'p': 35, 'a': 36, 'b': 37, 'c': 38, 'd': 39}, {'p': 40, 'a': 41, 'b': 42, 'c': 43, 'd': 44}, {'p': 45, 'a': 46, 'b': 47, 'c': 48, 'd': 49}]

[{'p': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4}, {'p': 5, 'a': 6, 'b': 7, 'c': 8, 'd': 9}, {'p': 10, 'a': 11, 'b': 12, 'c': 13, 'd': 14}, {'p': 15, 'a': 16, 'b': 17, 'c': 18, 'd': 19}, {'p': 20, 'a': 21, 'b': 22, 'c': 23, 'd': 24}, {'p': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29}, {'p': 30, 'a': 31, 'b': 32, 'c': 33, 'd': 34}, {'p': 35, 'a': 36, 'b': 37, 'c': 38, 'd': 39}, {'p': 40, 'a': 41, 'b': 42, 'c': 43, 'd': 44}, {'p': 45, 'a': 46, 'b': 47, 'c': 48, 'd': 49}]

第一种方法是创建每个字典,将从内容中获取的块与键配对。

就性能而言,

5.92 µs ± 42.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

第二种方法是,首先通过重复键旁边的内容来将内容与键配对,然后将这些成对的数据块打包成一个字典。

花费更少的时间,

5.76 µs ± 46.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

注意:如果输入元素的数量不是键的数量的倍数,则可以修改第一个解决方案以容纳部分字典

dicts = [dict((k,v) for k,v in zip(keys, gr) if v is not None) for gr in it.zip_longest(*[iter(content)]*len(keys))]

我知道向刚开始使用Python的人解释分块的工作原理并不容易。

如评论中所引用,请参阅此SO QA以获取更多详细信息