【问题标题】:Most pythonic way to convert a dict of lists into a list of dicts of all combs of the elements in the lists from the dict?将列表的字典转换为字典中列表中元素的所有梳的字典列表的最pythonic方法?
【发布时间】:2019-11-19 08:05:18
【问题描述】:

我有一本列表字典。我想生成这些列表的所有组合,并将这些组合作为具有正确键和值对映射的字典列表返回。

到目前为止,我已经通过部署下面的代码实现了这一点,但我想明确说明整个过程中的键值对映射,而不是依赖下面的枚举方法。我担心字典没有排序,枚举方法可能会以某种方式不正确映射键值对。无论如何,我正在寻找最pythonic的方式来实现结果。

import itertools

dct_lst = {'Apple':[3,5,7],'Pear':[5,2],'Orange':[10],'Banana':[7,10],'Lemon':[5,7,9,2,1]}

combs = itertools.product(*(dct_lst[key] for key in dct_lst.keys()))

lst_dct = []
for comb in combs:
    dct = {}
    for j,key in enumerate(dct_lst.keys()):
        dct[key] = comb[j]
    lst_dct.append(dct)

lst_dct

[{'Apple': 3, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 3, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 3, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 5, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 5, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 5},
 {'Apple': 7, 'Banana': 7, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 7, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 7, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 7, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 7, 'Lemon': 1, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 10, 'Lemon': 5, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 10, 'Lemon': 7, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 10, 'Lemon': 9, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 10, 'Lemon': 2, 'Orange': 10, 'Pear': 2},
 {'Apple': 7, 'Banana': 10, 'Lemon': 1, 'Orange': 10, 'Pear': 2}]

结果符合预期。不过,我对实现这一结果的最强大的 Python 方法很感兴趣。

【问题讨论】:

标签: python python-3.x list dictionary combinations


【解决方案1】:

您可以将键与值一起重复以构建项目列表:

>>> import itertools
>>> dct_lst = {'Apple':[3,5,7],'Pear':[5,2],'Orange':[10],'Banana':[7,10],'Lemon':[5,7,9,2,1]}
>>> L = [[(k, v) for v in vs] for k, vs in dct_lst.items()]
>>> L
[[('Apple', 3), ('Apple', 5), ('Apple', 7)], [('Pear', 5), ('Pear', 2)], [('Orange', 10)], [('Banana', 7), ('Banana', 10)], [('Lemon', 5), ('Lemon', 7), ('Lemon', 9), ('Lemon', 2), ('Lemon', 1)]]

并使用itertools.product 创建所有组合:

>>> list (itertools.product(*L))
[(('Apple', 3), ('Pear', 5), ('Orange', 10), ('Banana', 7), ('Lemon', 5)), (('Apple', 3), ('Pear', 5), ('Orange', 10), ('Banana', 7), ('Lemon', 7)), (('Apple', 3), ('Pear', 5), ('Orange', 10), ('Banana', 7), ('Lemon', 9)), ..., (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 7), ('Lemon', 2)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 7), ('Lemon', 1)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 10), ('Lemon', 5)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 10), ('Lemon', 7)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 10), ('Lemon', 9)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 10), ('Lemon', 2)), (('Apple', 7), ('Pear', 2), ('Orange', 10), ('Banana', 10), ('Lemon', 1))]

输出由元组组成,但很容易创建字典:

>>> list(map(dict, itertools.product(*L)))
[{'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, ..., {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 1}]

【讨论】:

  • 我在接受 jferard、Adam.Er8 和 benvc 的三个答案之间纠结(我都赞成)。这个答案似乎提供了最快的计算,但 benvc 的答案对我来说似乎稍微简单一些。非常感谢,并将让其他人的支持继续看到他们的决心!谢谢。
【解决方案2】:

您可以仅对字典的值使用itertools.product,然后将键和值一起使用dict(zip(...)) 以输出字典列表。

from itertools import product

d = {'Apple':[3,5,7],'Pear':[5,2],'Orange':[10],'Banana':[7,10],'Lemon':[5,7,9,2,1]}

l = [dict(zip(d.keys(), vals)) for vals in product(*d.values())]
print(l)
# [{'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 3, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 1}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 3, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 1}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 5, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 1}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 5, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 1}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 7, 'Pear': 5, 'Orange': 10, 'Banana': 10, 'Lemon': 1}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 5}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 7}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 9}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 2}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 7, 'Lemon': 1}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 5}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 7}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 9}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 2}, {'Apple': 7, 'Pear': 2, 'Orange': 10, 'Banana': 10, 'Lemon': 1}]

【讨论】:

    【解决方案3】:

    您可以使用ChianMap 帮助最后合并字典。

    试试这个:

    from itertools import product
    from collections import ChainMap
    
    dct_lst = {'Apple':[3,5,7],'Pear':[5,2],'Orange':[10],'Banana':[7,10],'Lemon':[5,7,9,2,1]}
    
    flat_dicts = [[{key: val} for val in lst] for key, lst in dct_lst.items()]
    lst_dct = list(map(lambda d: dict(ChainMap(*d)), product(*flat_dicts)))
    
    print(lst_dct)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-11
      • 2019-02-10
      • 2017-04-23
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多