来自Python字典数据的成对组合

时间:2015-10-14 05:41:28

标签: python dictionary combinations

我有一个不同类别的数据电子表格,我从csv读入字典,以列为主键。

我想从数据中进行成对组合,但似乎只能用键组合。

例如,如果我的数据是

{"x":['1','2','3'],
 "y":['4','5'],
 "z":['puddi']}

我已经使用itertools和itervalues(以及来自here的代码)来制定以下内容:

[{"x":['1','2','3'],"y":['4','5'},
 {"x":['1','2','3'],"z":['puddi']},
 ...]

我知道itervalues会返回我想用来进行成对组合的值,而itertools.product会产生我想要的组合,但是我很难将它们整合到所需的格式中:

{"x":['1','2','3','1','2','3'...],
 "y":['4','5','4',....],
 "z":['puddi','puddi','....]}

任何帮助都会有用

2 个答案:

答案 0 :(得分:0)

如果我们可以假设你事先知道字典的键,那么一种方法是 -

from itertools import product
result = {'x':[],'y':[],'z':[]}
for a,b,c in product(data['x'],data['y'],data['z']):  #data is the original dictionary
    result['x'].append(a)
    result['y'].append(b)
    result['z'].append(c)

以上内容将列表中的值(字典中的值)发送到itertools.product,然后将itertools.product产生的每个组合/产品添加到结果字典中的列表中。

演示 -

>>> data = {"x":['1','2','3'],
...  "y":['4','5'],
...  "z":['puddi']}
>>>
>>> from itertools import product
>>> result = {'x':[],'y':[],'z':[]}
>>> for a,b,c in product(data['x'],data['y'],data['z']):
...     result['x'].append(a)
...     result['y'].append(b)
...     result['z'].append(c)
...
>>> pprint.pprint(result)
{'x': ['1', '1', '2', '2', '3', '3'],
 'y': ['4', '5', '4', '5', '4', '5'],
 'z': ['puddi', 'puddi', 'puddi', 'puddi', 'puddi', 'puddi']}

通用解决方案 -

keys = list(data.keys()) #Or the list of keys you want Ex. - keys = ['x','y']
result = {k:[] for k in keys}
import operator
for item in product(*operator.itemgetter(*keys)(data)):
    for i, k in enumerate(keys):
            result[k].append(item[i])

演示 -

>>> keys = list(data.keys())
>>> result = {k:[] for k in keys}
>>> import operator
>>> for item in product(*operator.itemgetter(*keys)(data)):
...     for i, k in enumerate(keys):
...             result[k].append(item[i])
...
>>> pprint.pprint(result)
{'x': ['1', '2', '3', '1', '2', '3'],
 'y': ['4', '4', '4', '5', '5', '5'],
 'z': ['puddi', 'puddi', 'puddi', 'puddi', 'puddi', 'puddi']}

答案 1 :(得分:0)

这是一种方式:

d = {"x":['1','2','3'],
 "y":['4','5'],
 "z":['puddi']}
>>> {k: list(v) for k, v in zip(d.keys(), zip(*itertools.product(*d.values())))}
{'x': ['1', '2', '3', '1', '2', '3'],
 'y': ['4', '4', '4', '5', '5', '5'],
 'z': ['puddi', 'puddi', 'puddi', 'puddi', 'puddi', 'puddi']}

如你所说,值itertools.product会创建您想要的数据,但会进行转置,以便数据位于"行"而不是"列" (即第一行是"4", "1", "puddi")。使用zip(*...)对此进行转置,以便为每列获得一个元组。然后,您可以使用原始密钥对其进行压缩,以使用原始密钥重新对齐每个列。

您无法控制产品中行的顺序,因为这取决于字典中键的顺序,这是任意的。 (但是,正如documented一样,dict可以保证调用values然后keys生成对齐的值,这就是为什么我可以安全地单独调用它们如果您需要控制行的顺序,除了您的dict之外,您还必须使用一些有序的结构(例如,在Anand中的单独的键列表&# 39;以下答案。)