Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何解压缩迭代器?_Python_Iterator_Generator_Itertools - Fatal编程技术网

Python 如何解压缩迭代器?

Python 如何解压缩迭代器?,python,iterator,generator,itertools,Python,Iterator,Generator,Itertools,给定一个成对的列表xys,将其解压缩为两个列表的Python习惯用法是: xs, ys = zip(*xys) 如果xys是一个迭代器,我如何将其解压成两个迭代器,而不将所有内容存储在内存中?如果您想独立使用一个迭代器,就无法避免将内容拉入内存,因为其中一个迭代器将继续运行,而另一个迭代器则不会(因此必须缓冲) 类似这样的内容允许您迭代成对的“左项”和“右项”: import itertools import operator it1, it2 = itertools.tee(xys)

给定一个成对的列表
xys
,将其解压缩为两个列表的Python习惯用法是:

xs, ys = zip(*xys)

如果
xys
是一个迭代器,我如何将其解压成两个迭代器,而不将所有内容存储在内存中?

如果您想独立使用一个迭代器,就无法避免将内容拉入内存,因为其中一个迭代器将继续运行,而另一个迭代器则不会(因此必须缓冲)

类似这样的内容允许您迭代成对的“左项”和“右项”:

 import itertools
 import operator

 it1, it2 = itertools.tee(xys)
 xs = map(operator.itemgetter(0), it1))
 ys = map(operator.itemgetter(1), it2))

 print(next(xs))
 print(next(ys))
…但请记住,如果您只使用一个迭代器,则另一个迭代器将在内存中缓冲项,直到您开始使用它们


(顺便说一句,假设Python 3。在Python 2中,您需要使用
itertools.imap()
,而不是
map()

假设您有一些iterable对:

a = zip(range(10), range(10))
如果我正确地解释了您的要求,您可以使用以下方法为第一个和第二个生成独立的迭代器:

注意这将在内存中保留其中一个与另一个的迭代次数之间的“差异”。

完整答案。长话短说:我们可以修改Python配方以获得类似的结果

然后使用它

>>> from itertools import count
>>> zipped = zip(count(), count())
>>> xs, ys = unzip(zipped)
>>> next(xs)
0

“给定一个对XY的列表”所以类似于
[(1,2),(2,3),(3,4),…]
?你不需要拉上拉链;它已经是元组列表(或迭代器)。我想将xys转换为两个独立的迭代器xs=[1,2,3,…]和ys=[2,3,4,…],所以xys类似于
[[1,2,3],[2,3,4]
?然后,
itertools.izip
就是您想要的。这是一对列表,而不是一对列表。这并不能完全回答您的问题,但可能是您真正想要的:itertools.starmap。确实有一个警告:“此itertool可能需要大量的辅助存储(取决于需要存储的临时数据量)。通常,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,则使用
list()
而不是
tee()
会更快
from collections import deque


def unzip(iterable):
    """
    Transposes given iterable of finite iterables.
    """
    iterator = iter(iterable)
    try:
        first_elements = next(iterator)
    except StopIteration:
        return ()
    queues = [deque([element])
              for element in first_elements]

    def coordinate(queue):
        while True:
            if not queue:
                try:
                    elements = next(iterator)
                except StopIteration:
                    return
                for sub_queue, element in zip(queues, elements):
                    sub_queue.append(element)
            yield queue.popleft()

    return tuple(map(coordinate, queues))
>>> from itertools import count
>>> zipped = zip(count(), count())
>>> xs, ys = unzip(zipped)
>>> next(xs)
0