如何在python中多次使用迭代器

2024-04-27 00:58:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理一个需要多次使用迭代器的任务。比如说

   #data
   fruit= ("grape", "banana", "apple")
   #iterator
   myit = iter(fruit)

   #the function I have
   def printIter(its):
     for x in its:
        print(x)

   def printIter2(its):
     for x in its:
        print(x)

我必须在迭代器上调用printIter两次,但它要执行完全不同的函数。但是迭代器只能使用一次。 我无法控制数据源fruit和迭代器myit。我只能控制函数printIter()

我怎样才能用更少的记忆达到我的目标

我目前拥有的:

   it1, it2 = itertools.tee(its)
   printIter(it1)
   printIter(it2)
   del it1, it2

这是一个很好的做法吗,还有其他方式吗


Tags: 函数inapplefordatadefitsbanana
2条回答

由于迭代器是有状态的,并且它的资源被消耗,所以我不确定两次使用同一个迭代器的目标是什么

但是,如果您不希望在使用tee()时同时拥有迭代器的两个副本的内存开销,您可以在第一个副本被使用和删除后重新声明迭代器

import itertools

#the function I have
def printIter(its):
  for x in its:
    print(x)

def printIter2(its):
  for x in its:
    print(x)


#data
fruit= ("grape", "banana", "apple")

#iterator
myit = iter(fruit)

#it1, it2 = itertools.tee(myit)
printIter(myit)
del myit
myit = iter(fruit)
printIter2(myit)
del myit

由于您表示无法访问原始数据,tee()可能是迭代器的最佳选择。但是,您可以考虑将单个迭代器转换为列表,然后对其进行重复操作。

import itertools
#data
fruit= ("grape", "banana", "apple")
#iterator
myit = iter(fruit)

def printIter(its):
  for x in its:
    print(x)

mylist = list(myit)
del myit
printIter(mylist)
printIter(mylist)

如果您只有一个迭代器,并且需要在不消耗太多内存的情况下对其进行两种处理,那么最好的选择就是设计并行处理。也就是说,您需要能够一次处理一个项目的两个部分。在您的示例中,两个使用迭代器的函数都只是将其打印出来,这不利于并行化(您将以不同的顺序获得打印结果,例如1, 1, 2, 2, 3, 3, ...)。但对于其他类型的问题,很容易完成部分工作,然后等待更多数据

下面是一个示例,我使用两个生成器函数并行使用tee的迭代器(使用内置的zip)。一个将得到的值相加,只打印最终的和,另一个单独打印

def consume1(it):
    total = 0
    for value in it:
        total += value
        yield
    print(total)

def consume2(it):
    for value in it:
        print(value)
        yield

opaque_iterator = iter((1, 2, 3, 4))
it1, it2 = itertools.tee(opaque_iterator)

for _ in zip(consume1(it1), consume2(it2)):
    pass

输出:

1
2
3
4
10

这类代码有很多微妙之处,因此,如果您在第一次尝试时没有让它工作,请不要感到惊讶。我上面的代码非常脆弱,因为zip并不是专门为管理这样的独立生成器而设计的

相关问题 更多 >