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