【问题标题】:Is there a way to remember the position in a python iterator?有没有办法记住python迭代器中的位置?
【发布时间】:2014-03-02 21:22:28
【问题描述】:

我想遍历一个可迭代对象(比如说,一个列表),并在某个时刻记住我离开的位置,以便在下次调用该对象的迭代器时继续。

类似:

for val in list:
   do_stuff(val)
   if some_condition:
       break

do_stuff()

for val in list:
    continue_doing_stuff(val)

速度很重要,考虑的列表非常大。因此,保存对象并再次遍历整个列表直到找到保存的元素不是一种选择。如果不为列表编写显式迭代器类,这可能吗?

【问题讨论】:

    标签: python iterator generator


    【解决方案1】:

    __iter__ 方法在您进入带有对象的 for 循环时调用,并返回一个迭代器。我们通常不保留指向迭代器的名称,但如果这样做,我们可以停止迭代,执行其他操作,然后继续迭代。

    获取迭代器对象的最好方法是使用内置的iter函数:

    a_list = ['a', 'b', 'c', 'd']
    iter_list = iter(a_list)
    
    for val in iter_list:
       print(val)                # do_stuff(val)
       if val == 'b':            # some_condition!
           break
    
    print('taking a break')      # do_stuff()
    
    for val in iter_list:
        print(val)               # continue_doing_stuff(val)
    

    显示:

    a
    b
    taking a break
    c
    d
    

    iter(obj) 只是返回obj.__iter__() 的结果,它应该是一个实现.__next__() 方法的迭代器。

    每次迭代都会调用 __next__ 方法,返回对象(在这种情况下,是一个字符。)

    如果你想自己调用 __next__ 方法而不是让 for 循环调用它,你应该使用内置的 next 函数:

    a_list = ['a', 'b', 'c', 'd']
    iter_list = iter(a_list)
    print(next(iter_list))       # do_stuff(val)
    print(next(iter_list))
    print('taking a break')      # do_stuff()
    print(next(iter_list))       # continue_doing_stuff(val)
    print(next(iter_list))
    

    打印:

    a
    b
    taking a break
    c
    d
    

    【讨论】:

      【解决方案2】:

      您可以使用生成器来执行此操作

      def get_next(iterator):
          for item in iterator:
              yield item
      
      my_list_iterator = get_next(my_list)
      
      for val in my_list_iterator:
          do_stuff(val)
          if some_condition:
              break
      
      do_stuff()
      
      for val in my_list_iterator:
          continue_doing_stuff(val)
      

      【讨论】:

      • 您能否详细说明定义生成器比使用iter 有什么好处?据我所知get_next 的行为与iter(my_list) 相同。两种方法都应该有效,但我通常更喜欢在它们完成所有需要时使用内置函数。
      • @PeterDeGlopper 对于这个特殊情况iter 应该没问题。
      • 谢谢,看来我们普遍同意。鉴于我对内置函数的偏好,我略微不同意@yopy 的评论“这应该是答案”(尽管我并不声称这个答案是错误的——这是一种完全有效的方法),也许我应该相应地处理我的评论。在它们之间进行选择看起来像是在明确声明的行为与内置行为之间进行选择,这是非常主观的。
      • 我收回了我的话,iter(iterables) 可以解决他对这个特殊情况的需求。感谢您的反馈。
      猜你喜欢
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 2011-11-04
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      相关资源
      最近更新 更多