了解T恤的缓冲

时间:2014-04-17 07:09:53

标签: python list-comprehension lazy-evaluation

在阅读了代码tee的{​​{3}}之后,我玩了一会儿,试图概括那里提供的解决方案。

任务是懒洋洋地转移"转移"一个列表。也就是说,列表[xrange(1, 4), xrange(4, 7), xrange(7, 10)](在python 2.7中)必须成为类似[xrange(1, 10, 3), xrange(2, 10, 3), xrange(3, 10, 3)]的东西。

我在这里复制了那里提出的解决方案:

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])

我的概括是关于尝试做同样的事情,其中​​3是一个参数。由于3是输入生成器的长度,因此您无法猜测它,并且必须将其添加为函数的参数。由于某些生成器可能很大甚至无限,我也将此参数视为限制,因此我们仅从每个输入生成器中获取第一个 n 元素。

这是我的代码:

def transpose(zipped, n):
    teed = tee(zipped, n)
    return [(e[i] for e in teed[i]) for i in xrange(n)]

这不能按预期工作,如下例所示:

>>> data = [xrange(1, 4), xrange(4, 7), xrange(7, 10)]
>>> x, y, z = transpose(data, 3)
>>> x.next()
3

(我预计1)。

我想这是关于列表理解中的生成器和名称泄漏,或i或类似内容的惰性评估......你能说出我的代码有什么问题以及它是怎么回事可以修好吗?

1 个答案:

答案 0 :(得分:0)

感谢@ BrenBarn的评论,这是一个(非常难看)补丁修复。不过,欢迎你提出更好的建议。

def transpose(zipped, n):                          
    teed = tee(zipped, n)                            
    for i in xrange(n):
        gen = lambda teed, i=i: (e[i] for e in teed[i])
        yield gen(teed)