如何反转itertools.chain对象?

Ste*_*der 9 python generator python-itertools

我的函数创建了一个生成器链:

def bar(num):
    import itertools
    some_sequence = (x*1.5 for x in range(num))
    some_other_sequence = (x*2.6 for x in range(num))
    chained = itertools.chain(some_sequence, some_other_sequence)
    return chained
Run Code Online (Sandbox Code Playgroud)

我的功能有时需要以chained相反的顺序返回.从概念上讲,以下是我希望能够做到的:

if num < 0:
    return reversed(chained)
return chained
Run Code Online (Sandbox Code Playgroud)

不幸:

>>> reversed(chained)
TypeError: argument to reversed() must be a sequence
Run Code Online (Sandbox Code Playgroud)

我有什么选择?

这是一些实时的图形渲染代码,所以我不想让它太复杂/慢.

编辑:当我第一次提出这个问题时,我没有考虑过发电机的可逆性.正如许多人所指出的那样,发电机无法逆转.

事实上,我想要扭转链条中扁平化的内容; 不仅仅是发电机的顺序.

根据响应,我没有单一的调用来反转itertools.chain,所以我认为这里唯一的解决方案是使用一个列表,至少在相反的情况下,也许两者都有.

sha*_*ang 10

if num < 0:
    lst = list(chained)
    lst.reverse()
    return lst
else:
    return chained
Run Code Online (Sandbox Code Playgroud)

reversed() 需要一个实际的序列,因为它通过索引向后迭代它,这对于生成器(它只有"下一个"项的概念)不起作用.

由于您无论如何都需要展开整个生成器以进行反转,因此最有效的方法是将其读取到列表并使用该.reverse()方法就地反转列表.

  • 是的,但如果您需要访问一般情况下的最后一项(通过倒车隐含),则必须耗尽发电机.没有看到真正的代码,就不可能提供更好的解决方案. (7认同)

Joc*_*zel 9

根据定义,您无法反转生成器.生成器的接口是迭代器,它是一个仅支持前向迭代的容器.当你想要反转迭代器时,你必须先收集它的所有项目,然后再反转它们.

改为使用列表或从头开始向后生成序列.