itertools.izip()表示未预定义的列表计数

时间:2013-01-24 17:23:21

标签: python itertools

我有以下数据结构:{'one':['a','b','c'],'two':['q','w','e'],'three':['t','u','y'],...}。因此,字典具有不同的键数。由dict的键选取的每个数组具有相似的长度。我如何将此结构转换为以下内容:[{'one':'a','two':'q','three':'t'},{'one':'b','two':'w','three':'y'},...]

我想我应该使用itertools.izip(),但我如何应用它而不是预定义的args数?也许是这样的:itertools.izip([data[l] for l in data.keys()])

TIA!

2 个答案:

答案 0 :(得分:2)

不是非常优雅,但有诀窍:

In [9]: [{k:v[i] for (k,v) in d.items()} for i in range(len(d.values()[0]))]
Out[9]: 
[{'one': 'a', 'three': 't', 'two': 'q'},
 {'one': 'b', 'three': 'u', 'two': 'w'},
 {'one': 'c', 'three': 'y', 'two': 'e'}]

我不禁想到必须有更好的方法来表达i循环,但现在没有想到任何事情。

可替换地:

In [50]: map(dict, zip(*[[(k, v) for v in l] for k, l in d.items()]))
Out[50]: 
[{'one': 'a', 'three': 't', 'two': 'q'},
 {'one': 'b', 'three': 'u', 'two': 'w'},
 {'one': 'c', 'three': 'y', 'two': 'e'}]

不确定这在可读性方面是否有很大改善。

答案 1 :(得分:1)

您使用izip时的评估是正确的,但使用它的方式并不正确

您首先需要

  • 将项目作为元组列表(键,值),(如果使用Py2.x,则使用iteritems()方法;如果使用Py3.x,则使用items()
  • 创建关键和值的标量产品
  • 压扁列表(使用itertools.chain)
  • 压缩它(使用itertools.izip)
  • 然后创建每个元素的字典

以下是示例代码

>>> from pprint import PrettyPrinter
>>> pp = PrettyPrinter(indent = 4)
>>> pp.pprint(map(dict, izip(*chain((product([k], v) for k, v in data.items())))))
[   {   'one': 'a', 'three': 't', 'two': 'q'},
    {   'one': 'b', 'three': 'u', 'two': 'w'},
    {   'one': 'c', 'three': 'y', 'two': 'e'}]
>>>