0

我有一个默认字典列表:

default = [{"One": 1, "Two": 2, "Three": 3}, {"One": 5, "Two": 6, "Three": 7},
{"One": 9, "Two": 10, "Three" : 11}]

全部使用相同的键。我有一个从键到列表的单独字典:

varying = {"One": [12,13,14,15], "Two": [20,21,23], "Three": [12,44]}

我想要做的是列出所有可能的字典,方法是通过将默认字典之一中的值之一更改为可变字典中的相应值之一。以下是最终列表中的字典示例:

{"One": 12, "Two": 2, "Three": 3}
{"One": 13, "Two": 2, "Three": 3}
{"One": 14, "Two": 6, "Three": 7}
{"One": 15, "Two": 10, "Three": 11}
{"One": 5, "Two": 20, "Three": 7}
{"One": 9, "Two": 23, "Three": 11}
{"One": 1, "Two": 2, "Three": 44}

所以总的来说有 (4+3+2)*3=27 种可能性。我能够让它接近工作,但问题是它变得非常混乱。有什么干净的方法可以做到这一点吗?

4

3 回答 3

4
default = [{"One": 1, "Two": 2, "Three": 3}, {"One": 5, "Two": 6, "Three": 7},
           {"One": 9, "Two": 10, "Three" : 11}]
varying = {"One": [12,13,14,15], "Two": [20,21,23], "Three": [12,44]}

result = [dict(d.items() + [(k, x)])
              for d in default for k, v in varying.items() for x in v]

>>> result
[{'One': 1, 'Three': 12, 'Two': 2},
 {'One': 1, 'Three': 44, 'Two': 2},
 {'One': 1, 'Three': 3, 'Two': 20},
 {'One': 1, 'Three': 3, 'Two': 21},
 {'One': 1, 'Three': 3, 'Two': 23},
 {'One': 12, 'Three': 3, 'Two': 2},
 {'One': 13, 'Three': 3, 'Two': 2},
 {'One': 14, 'Three': 3, 'Two': 2},
 {'One': 15, 'Three': 3, 'Two': 2},
 {'One': 5, 'Three': 12, 'Two': 6},
 {'One': 5, 'Three': 44, 'Two': 6},
 {'One': 5, 'Three': 7, 'Two': 20},
 {'One': 5, 'Three': 7, 'Two': 21},
 {'One': 5, 'Three': 7, 'Two': 23},
 {'One': 12, 'Three': 7, 'Two': 6},
 {'One': 13, 'Three': 7, 'Two': 6},
 {'One': 14, 'Three': 7, 'Two': 6},
 {'One': 15, 'Three': 7, 'Two': 6},
 {'One': 9, 'Three': 12, 'Two': 10},
 {'One': 9, 'Three': 44, 'Two': 10},
 {'One': 9, 'Three': 11, 'Two': 20},
 {'One': 9, 'Three': 11, 'Two': 21},
 {'One': 9, 'Three': 11, 'Two': 23},
 {'One': 12, 'Three': 11, 'Two': 10},
 {'One': 13, 'Three': 11, 'Two': 10},
 {'One': 14, 'Three': 11, 'Two': 10},
 {'One': 15, 'Three': 11, 'Two': 10}]

这是使用普通 for 循环而不是列表推导的等价物:

result = []
for d in default:
    for k, v in varying.items():
        for x in v:
            result.append(dict(d.items() + [(k, x)]))

请注意,在 Python 3.x 上,您需要list(d.items())使用d.items().

于 2013-08-23T18:08:39.220 回答
2

一个简单的解决方案是:

[ { "One":d["One"], "Two":d["Two"], "Three":d["Three"], i:v }
  for d in default
  for i in ["One","Two","Three"]
  for v in varying[i]
]

或者

[ dict( list(d.items()) + list({i:v}.items()) )
  for d in default
  for i in ["One", "Two", "Three"]
  for v in varying[i]
]

或者

[ dict( list(d.items()) + [(i,v)] )
  for d in default
  for i in ["One", "Two", "Three"]
  for v in varying[i]
]

测试时,所有三个都会产生由 27 个元素组成的预期结果。

另请注意,对于更大的数据集,这些形式可能会超过执行时间限制。

于 2013-08-23T18:25:31.703 回答
1

没有itertools

default = [{"One": 1, "Two": 2, "Three": 3}, {"One": 5, "Two": 6, "Three": 7},
{"One": 9, "Two": 10, "Three" : 11}]
varying = {"One": [12,13,14,15], "Two": [20,21,23], "Three": [12,44]}
variations = []

for dic in default:
    for key in varying:
        for val in varying[key]:
            new_dict = dict(dic)
            new_dict[key] = val  
            variations.append(new_dict)

print variations

如果您不使用itertools,那么此代码至少需要具有这三个循环,这只是您问题的性质。

于 2013-08-23T18:05:53.290 回答