生成器生成列表

时间:2012-03-23 17:15:10

标签: python generator

我有三个列表列表,我正在尝试编写一个生成器函数来帮助我在同一个索引中打包值。

所以我的名单:

list1 = [[1, 2, 3], [2, 3, 4],...]
list2 = [[4, 5, 6], [5, 6, 7],...]
list3 = [[8, 9, 10], [9, 10, 11],...]

我想要的输出:

result1 = [[1, 4, 8], [2, 5, 9],...]
result2 = [[2, 5, 9], [3, 6, 10],...]
result3 = [[3, 6, 10], [4, 7, 11],...]

我的尝试:

def bundle(x, y, z, index):
    for row in x, y, z:
        for item in row[index]:
            yield list(item)

我不断浮动不是可迭代的错误。如果我稍微修改它:

def bundle(x, y, z, index):
    for row in x, y, z:
        for item in row:
            yield item[index]

我得到了我想要的值作为一个大序列,但我宁愿将它们分组为嵌套样式。

3 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是重复应用zip()

res1, res2, res3 = zip(*(zip(*x) for x in zip(list1, list2, list3)))

这使用zip(list1, list2, list3)创建一个矩阵序列,zip(*x)来转置每个矩阵,并使用最终zip()解压缩到三个结果序列。 (我不认为这种方法非常有效。)

答案 1 :(得分:2)

如果您正在处理数值,那么您可以使用numpy的转置方法来实现您想要的效果:

import numpy
numpy.array([list1,list2, list3]).T

答案 2 :(得分:2)

如果你正在处理大型列表,那么自定义,完全懒惰的方法如下:

import itertools as it

def bundle(lists, index):
  return ([b[index] for b in blocks] for blocks in it.izip(*lists))

print list(bundle([[[1, 2, 3],  [2, 3, 4]], 
                   [[4, 5, 6],  [5, 6, 7]], 
                   [[8, 9, 10], [9, 10, 11]]], 
                  0))
# => [[1, 4, 8], [2, 5, 9]]