我想遍历一个可迭代的对象(比如说,一个列表),并在某个时候记住我离开的位置,以便在下次调用该对象的迭代器时继续。
像这样:
for val in list:
do_stuff(val)
if some_condition:
break
do_stuff()
for val in list:
continue_doing_stuff(val)
速度很重要,考虑的清单非常大。因此,保存对象并再次循环访问整个列表,直到找到保存的元素不是一种选择。如果不为列表编写显式迭代器类,这是否可能?
当您使用对象进入 for 循环并返回迭代器时,将调用__iter__
方法。我们通常不会保留指向迭代器的名称,但如果这样做,我们可以停止迭代,做其他事情,然后继续迭代。
获取迭代器对象的最佳方法是使用内置的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
您可以使用生成器来执行此操作
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)