【问题标题】:Python create combinations of dictionaryPython创建字典组合
【发布时间】:2019-03-07 09:18:06
【问题描述】:

我想转换以下形式的 Python 字典:

D = {'a':[1,2,3], 'b':[0.1,0.5], 'c':[10,20]}

按以下形式放入字典列表:

E = [{a:1,b:0.1,c:10}, {a:1,b:0.1,c:20},{a:1,b:0.5,c:10}, ...., {a:3,b:0.5,c:20}]

我尝试过使用 itertools,但我不明白如何使用它来组合字典。

【问题讨论】:

  • 你用itertools完成了什么?您是否成功地制作了列表的笛卡尔积?

标签: python dictionary iteration combinations


【解决方案1】:

这里有一个解决方案:

import itertools

D = {'a':[1,2,3], 'b':[0.1,0.5], 'c':[10,20]}

E = [dict(zip(D.keys(), a)) for a in itertools.product(*D.values())]

这会产生:

E= [{'a': 1, 'b': 0.1, 'c': 10},
 {'a': 1, 'b': 0.1, 'c': 20},
 {'a': 1, 'b': 0.5, 'c': 10},
 {'a': 1, 'b': 0.5, 'c': 20},
 {'a': 2, 'b': 0.1, 'c': 10},
 {'a': 2, 'b': 0.1, 'c': 20},
 {'a': 2, 'b': 0.5, 'c': 10},
 {'a': 2, 'b': 0.5, 'c': 20},
 {'a': 3, 'b': 0.1, 'c': 10},
 {'a': 3, 'b': 0.1, 'c': 20},
 {'a': 3, 'b': 0.5, 'c': 10},
 {'a': 3, 'b': 0.5, 'c': 20}]

编辑:删除了 Aran 指出的有序字典,这是支持它的文档:Python dictionary: are keys() and values() always the same order?

【讨论】:

  • OrderedDict 在这里不是必需的。虽然是的,但 dict 迭代顺序是任意的,它不会无缘无故地神奇地改变。只有当你修改字典时它才能改变,而你没有这样做。
【解决方案2】:

为什么不只是:

from itertools import product
D = {'a':[1,2,3], 'b':[0.1,0.5], 'c':[10,20]}
print([dict(zip(D.keys(),v)) for v in product(*D.values())])

输出:

[{'a': 1, 'b': 0.1, 'c': 10}, {'a': 1, 'b': 0.1, 'c': 20}, {'a': 1, 'b': 0.5, 'c': 10}, {'a': 1, 'b': 0.5, 'c': 20}, {'a': 2, 'b': 0.1, 'c': 10}, {'a': 2, 'b': 0.1, 'c': 20}, {'a': 2, 'b': 0.5, 'c': 10}, {'a': 2, 'b': 0.5, 'c': 20}, {'a': 3, 'b': 0.1, 'c': 10}, {'a': 3, 'b': 0.1, 'c': 20}, {'a': 3, 'b': 0.5, 'c': 10}, {'a': 3, 'b': 0.5, 'c': 20}]

【讨论】:

    【解决方案3】:

    一种选择是简单地使用嵌套的 for 循环;如果原始数据不是太大,那么这将正常工作,您不需要itertools 即可使其正常工作。

    >>> origin = {
        'a': [1, 2, 3],
        'b': [0.1, 0.5],
        'c': [10, 20],
    }
    >>> result = [
        {
            'a': a,
            'b': b,
            'c': c,
        }
        for a in origin['a']
        for b in origin['b']
        for c in origin['c']]
    >>> result
    [{'a': 1, 'b': 0.1, 'c': 10}, {'a': 1, 'b': 0.1, 'c': 20},
     {'a': 1, 'b': 0.5, 'c': 10}, {'a': 1, 'b': 0.5, 'c': 20},
     {'a': 2, 'b': 0.1, 'c': 10}, {'a': 2, 'b': 0.1, 'c': 20},
     {'a': 2, 'b': 0.5, 'c': 10}, {'a': 2, 'b': 0.5, 'c': 20},
     {'a': 3, 'b': 0.1, 'c': 10}, {'a': 3, 'b': 0.1, 'c': 20},
     {'a': 3, 'b': 0.5, 'c': 10}, {'a': 3, 'b': 0.5, 'c': 20}]
    

    【讨论】:

    • 如果有很多键或 OP 不知道任何键会怎样?
    • @U9-Forward 我的答案对于更多的密钥不是很实用,而且不是真正可扩展的;但由于该问题没有将可扩展性指定为要求,因此我想为所有 itertools 答案添加替代解决方案。
    【解决方案4】:

    我开发了一个关于答案的回合

    parameter_values_each = {'a':[1,2,3], 'b':[0.1,0.5], 'c':[10,20]}
    
    param_possibilities = []
    for name in parameter_values_each:
        temp = []
        for val in parameter_values_each[name]:
            temp.append((name,val))
        param_possibilities.append(temp)
    
    
    result = list(itertools.product(*param_possibilities))
    
    print result
    

    【讨论】:

      【解决方案5】:

      没有 itertools 的路很长(或者这就是 product 内部发生的事情):

      D = {'a': [1, 2, 3], 'b': [0.1, 0.5], 'c': [10, 20]}
      E = []
      
      list_of_keys = list(D.keys())
      list_of_lengths = [len(D[key]) for key in list_of_keys]
      
      product_number = 1
      for length in list_of_lengths:
          product_number *= length
      
      for n in range(product_number):
          index = n
          index_list = []
          for length in reversed(list_of_lengths):
              index_list.insert(0, index % length)
              index = index // length
          keys_with_values = {}
          for j, key in enumerate(list_of_keys):
              keys_with_values[key] = D[key][index_list[j]]
          E.append(keys_with_values)
      
      for e in E:
          print(e)
      

      结果:

      {'a': 1, 'b': 0.1, 'c': 10}
      {'a': 1, 'b': 0.1, 'c': 20}
      {'a': 1, 'b': 0.5, 'c': 10}
      {'a': 1, 'b': 0.5, 'c': 20}
      {'a': 2, 'b': 0.1, 'c': 10}
      {'a': 2, 'b': 0.1, 'c': 20}
      {'a': 2, 'b': 0.5, 'c': 10}
      {'a': 2, 'b': 0.5, 'c': 20}
      {'a': 3, 'b': 0.1, 'c': 10}
      {'a': 3, 'b': 0.1, 'c': 20}
      {'a': 3, 'b': 0.5, 'c': 10}
      {'a': 3, 'b': 0.5, 'c': 20}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-11
        • 2018-04-30
        • 1970-01-01
        • 1970-01-01
        • 2017-07-14
        • 1970-01-01
        • 2014-10-02
        相关资源
        最近更新 更多