【问题标题】:Appending multiple for-loop outputs to a list将多个 for 循环输出附加到列表
【发布时间】:2020-07-23 07:30:29
【问题描述】:

我正在使用 RegEx 从 txt 文件中提取一些数据。我制作了以下 for 循环来提取电子邮件和生日,并(尝试)将输出附加到列表中。但是当我打印我的列表时,只打印第一个附加的输出。 birtdate RegEx 在单独运行时工作正常。我确定我在做一些非常基本的错误。

f = open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8")

list = []

for i in f:
    if re.findall(r"((?i)[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.])", i):
        list.append(i)

for k in f:
    if re.findall(r'\d\d-\d\d-\d\d\d\d', k):
        list.append(k)

print(list)
f.close()

【问题讨论】:

  • 不是答案,只是注意到您在第一个模式中使用了不区分大小写的修饰符(?i)。所以你可以摆脱A-Z。同样在您的第二个正则表达式中 > \d\d\d\d 最好写成 \d{4}
  • 这能回答你的问题吗? Read multiple times lines of the same file Python
  • 当您进入第二个循环时,您的迭代器 f 已经到达文件末尾 (EOF)。所以你要么需要在第二个循环之前做f.seek(0),要么只需要| 两个正则表达式,我认为管道两个正则表达式应该可以正常工作

标签: python for-loop append


【解决方案1】:

试试这个:

with open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8") as f:
    i = f.readline()
    if re.findall(r"((?i)[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.])", i):
        list.append(i)
    if re.findall(r'\d\d-\d\d-\d\d\d\d', k):
        list.append(i)

在您的代码中,在第一个 for 循环之后, f 现在指向文件的末尾,因此第二个 for 循环不会像您希望的那样“运行”。

因此,要修改您的代码以使其执行您想要的操作,您将在第一个循环之后关闭文件并在第二个循环之前重新打开它,以便文件指针 f 再次指向文件的开头:

f = open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8")

list = []

for i in f:
    if re.findall(r"((?i)[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.])", i):
        list.append(i)

f.close()

f = open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8")
for k in f:
    if re.findall(r'\d\d-\d\d-\d\d\d\d', k):
        list.append(k)

print(list)
f.close()

【讨论】:

  • 请在回答时向 OP 解释它的错误,以及您的代码如何修复它。 SO 的主要目标是让人们学习东西,而不是复制行之有效的代码
【解决方案2】:

您尝试读取同一个文件两次。第二个 for 循环不会做任何事情。看看这个就明白了:

f = open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8")
print(list(f))
print("second time:")
print(list(f))

输出:

['1234567890abcdefghijklmopqrstuvwxyz'] # or whatever your content is :)
second time:
[]

要解决此问题,您可以将文件的结果存储在列表中(当然,如果您不处理大文件):

f = open("/Users/me/Desktop/scrape.txt", "r", encoding="utf8")
content = list(f)


for i in content:
   ... 

for k in content:
   ... 

不过,在您的具体示例中,在单个 for 循环中完成所有处理会更简洁(更快)。但是,错误是尝试从同一个文件中读取两次而不重置它。

【讨论】:

  • 请注意,如果文件很大,将其存储为列表可能会导致列表的大小非常大。
  • 是的。我只是希望电子邮件和生日列表不要以百万计。
  • @abhinonymous :添加了关于此的注释。
  • 想象一下在 wiki 转储上这样做,我敢肯定有人在某个时间点这样做过 :)
猜你喜欢
  • 1970-01-01
  • 2023-01-07
  • 2020-05-26
  • 1970-01-01
  • 2020-09-25
  • 2021-09-21
  • 2015-04-27
  • 2013-05-18
  • 2020-03-02
相关资源
最近更新 更多