【问题标题】:Explode a dict - Get all combinations of the values in a dictionaryExplode a dict - 获取字典中值的所有组合
【发布时间】:2017-05-06 08:54:13
【问题描述】:

我想将字典中值的所有组合作为多个字典(每个字典包含原始的每个键,但仅包含原始值的一个值)。假设我想参数化一个函数调用:

kwargs = {'a': [1, 2, 3], 'b': [1, 2, 3]}

如何获得所有组合的列表,如下所示:

combinations = [{'a': 1, 'b': 1}, {'a': 1, 'b': 2}, {'a': 1, 'b': 3},
                {'a': 2, 'b': 1}, {'a': 2, 'b': 2}, {'a': 2, 'b': 3},
                {'a': 3, 'b': 1}, {'a': 3, 'b': 2}, {'a': 3, 'b': 3}]

原始kwargs 中可以有任意数量的键,每个值都保证是可迭代的,但值的数量不固定。

如果可能:最后的 combinations 应该是生成器(而不是列表)。

【问题讨论】:

    标签: python dictionary cartesian-product


    【解决方案1】:

    另一种方式,首先构建值元组,然后再与键组合(与@thefourtheye 的方式几乎相反 :-)。

    >>> combinations = (dict(zip(kwargs, vs)) for vs in product(*kwargs.values()))
    >>> for c in combinations:
            print(c)
    
    {'a': 1, 'b': 1}
    {'a': 1, 'b': 2}
    {'a': 1, 'b': 3}
    {'a': 2, 'b': 1}
    {'a': 2, 'b': 2}
    {'a': 2, 'b': 3}
    {'a': 3, 'b': 1}
    {'a': 3, 'b': 2}
    {'a': 3, 'b': 3}
    

    【讨论】:

    • 这不取决于实现细节,因为它要求键和值迭代器具有相同的顺序吗? Dict 没有排序要求,我认为不能保证这些迭代器必须具有相同的顺序。
    • @zstewart 为什么不检查文档?它说他们有相同的顺序,甚至给出了例子pairs = zip(d.values(), d.keys())
    • @StefanPochmann 你是说"Dictionary view objects" documentation
    【解决方案2】:

    您可以将kwargs 展平为类似的内容

    >>> kwargs = {'a': [1, 2, 3], 'b': [1, 2, 3]}
    >>> flat = [[(k, v) for v in vs] for k, vs in kwargs.items()]
    >>> flat
    [[('b', 1), ('b', 2), ('b', 3)], [('a', 1), ('a', 2), ('a', 3)]]
    

    然后,你可以像这样使用itertools.product

    >>> from itertools import product
    >>> [dict(items) for items in product(*flat)]
    [{'a': 1, 'b': 1},
     {'a': 2, 'b': 1},
     {'a': 3, 'b': 1},
     {'a': 1, 'b': 2},
     {'a': 2, 'b': 2},
     {'a': 3, 'b': 2},
     {'a': 1, 'b': 3},
     {'a': 2, 'b': 3},
     {'a': 3, 'b': 3}]
    

    itertools.product 实际上返回一个迭代器。因此,您可以按需获取值并构建您的字典。或者你可以使用map,它也返回一个迭代器。

    >>> for item in map(dict, product(*flat)):
    ...     print(item)
    ...
    ...
    {'b': 1, 'a': 1}
    {'b': 1, 'a': 2}
    {'b': 1, 'a': 3}
    {'b': 2, 'a': 1}
    {'b': 2, 'a': 2}
    {'b': 2, 'a': 3}
    {'b': 3, 'a': 1}
    {'b': 3, 'a': 2}
    {'b': 3, 'a': 3}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 2016-01-27
      • 2020-11-23
      • 2017-08-07
      • 2016-11-14
      相关资源
      最近更新 更多