所以,我有一个3元组的可迭代,懒得生成。我试图找出如何将其转换为3个迭代,分别由元组的第一,第二和第三个元素组成。但是,我希望这可以懒惰地完成。
因此,例如,我希望将[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
转换为[1, 4, 7]
,[2, 5, 8]
,[3, 6, 9]
。 (除非我希望iterables不是列表。)
标准zip(*data)
成语不起作用,因为参数解包扩展了整个可迭代。 (您可以通过注意zip(*((x, x+1, x+2) for x in itertools.count(step=3)))
挂起来验证这一点。)
到目前为止,我提出的最好成绩如下:
def transpose(iterable_of_three_tuples):
teed = itertools.tee(iterable_of_three_tuples, 3)
return map(lambda e: e[0], teed[0]), map(lambda e: e[1], teed[1]), map(lambda e: e[2], teed[2])
这似乎有效。但它似乎不像干净的代码。而且它做了很多看似不必要的工作。
答案 0 :(得分:3)
您的transpose
几乎就是您所需要的。
使用您选择的任何解决方案,您必须缓冲未使用的值(例如,要获得7,您必须阅读1-6,并将其存储在内存中以供其他迭代使用时问他们)。 tee
已经完成了那种缓冲,所以不需要自己实现它。
唯一的另一个(次要的)是,我的写法略有不同,避免使用map
和lambda
:
def transpose(iterable_of_three_tuples):
teed = itertools.tee(iterable_of_three_tuples, 3)
return ( e[0] for e in teed[0] ), ( e[1] for e in teed[1] ), ( e[2] for e in teed[2] )