首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么迭代器在遍历后是空的?

为什么迭代器在遍历后是空的?
EN

Stack Overflow用户
提问于 2022-07-05 15:36:10
回答 2查看 106关注 0票数 0

下面的代码迭代由

代码语言:javascript
复制
matches = pattern.finditer(text_to_search)

稍后,我尝试将此对象视为列表,但此列表为空。当我将这个请求放在迭代之前,我会得到正确的列表。然后迭代本身停止工作,结果将不显示。我认为这里有一些类似于读取文件的内容,但是可以使用.seek()方法回到开头。我不知道如何处理可调用的迭代器,同样的方法在这里不适用。对不起,对这个问题的解释很差,我不知道如何更好地描述它。

代码语言:javascript
复制
import re

text_to_search = '''
abcdefghijklmnopqurtuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1234567890

Ha HaHa

MetaCharacters (Need to be escaped):
. ^ $ * + ? { } [ ] \ | ( )

coreyms.com

321-555-4321
123.555.1234abc
123*555*1234
800-555-1234
900-555-1234

Mr. Schafer
Mr Smith
Ms Davis
Mrs. Robinson
Mr. T
'''

sentence = 'Start a sentence and then bring it to an end'

pattern = re.compile(r'abc')

matches = pattern.finditer(text_to_search)

for match in matches:
    print(match)

print(matches)

print(list(matches))

代码结果:

代码语言:javascript
复制
<re.Match object; span=(1, 4), match='abc'>
<re.Match object; span=(180, 183), match='abc'>
<callable_iterator object at 0x00000269F1DD5390>
[]

!!名单是空的!!

测试的代码修改:

代码语言:javascript
复制
print(list(matches)) #this line of code was moved up
for match in matches:
    print(match)

print(matches)

#from there

所产生的结果:

代码语言:javascript
复制
[<re.Match object; span=(1, 4), match='abc'>, <re.Match object; span=(180, 183), match='abc'>]
<callable_iterator object at 0x00000116F35D5390>

!!结果中缺少一个迭代!!

EN

回答 2

Stack Overflow用户

发布于 2022-07-05 15:40:34

finditer返回一个迭代器。根据定义,迭代器可以迭代一次,生成所有值,然后耗尽。拥有seek方法的类文件对象是一个例外;大多数迭代器不能重置。

如果您需要多次重用迭代器,那么就先将其转换为listtuple,存储它产生的所有值,然后根据您的意愿多次迭代list/tuple,例如:

代码语言:javascript
复制
matches = list(pattern.finditer(text_to_search))  # Eagerly exhaust iterator, converting to list

for match in matches:  # Each use of list for iteration makes new iterator over same data
    print(match)

print(matches)        # Prints the list

print(list(matches))  # Makes an unnecessary copy of the list

一般来说,Python3已经倾向于返回视图和迭代器的函数,而不是返回list的函数;在很少需要的情况下,前者可以很小地转换为后者(只需将它们包装在list()中),而且在大多数情况下,您实际上并不需要所有的值,或者在存储它们之前对它们进行筛选或调整,或者您希望在完成迭代之前停止,所以迭代器方法意味着在开始处理之前减少大的临时时间,更短的延迟,以及在您提前结束循环时避免完全完成工作的能力。

您可以阅读更多关于the difference between itera_tor_s and itera_ble_s here的内容。

票数 1
EN

Stack Overflow用户

发布于 2022-07-05 15:39:59

正如您所观察到的,迭代器的工作方式非常类似于文件句柄,除了不存在能够返回到开头的seek的概念,因为没有任何东西是持久保存的;一旦迭代器耗尽,它就永远消失了。

如果希望能够再次遍历匹配,请保存列表(类似于将文件保存在磁盘上,但内存中的文件除外):

代码语言:javascript
复制
matches = list(pattern.finditer(text_to_search))
for match in matches:
    print(match)

现在,您可以任意重用matches,因为原始迭代器中的每个项都已保存到列表中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72872085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档