【问题标题】:Removing items from a list in python following validity check [duplicate]有效性检查后从python列表中删除项目[重复]
【发布时间】:2023-03-15 08:05:01
【问题描述】:

背景:

我正在编写一个小脚本,它需要一个文件中的电子邮件地址列表作为它的参数之一。该脚本将让他们继续通过 telnet 连接到 SMTP 服务器使用电子邮件地址,因此它们需要在语法上有效;因此我放了一个检查电子邮件地址有效性的功能(顺便说一下,这个正则表达式可能并不完美,但不是问题的重点,请多多包涵。可能会放松):

def checkmailsyntax(email):
    match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email)

    if match == None:
        return True

main() 程序继续读取输入文件名作为参数(在 argparse 中)并将其插入到(当前是全局的)列表中:

with open(args.targetfile) as targets:
    target_email_list = targets.readlines()

我认为如果checkmailsyntax 函数失败,脚本会自动从列表中删除一个电子邮件地址(而不是仅仅告诉你它过去的做法是错误的)。然后,这个清理后的列表可以继续向 SMTP 服务器提交语法上有效的电子邮件地址:

for i in target_email_list:
    if checkmailsyntax(i):
        target_email_list.remove(i)

我在删除元素 sn-p 之前和之后输入的错误检查代码,以查看它是否在做它的工作:

for i in target_email_list:
    print i

问题:代码的输出如下:

删除元素前sn -p(以及提交的文件的全部内容):

me@example.com  
you@example.com  
them@example.com  
noemail.com  
incorrectemail.com  
new@example.com  
pretendemail.com  
wrongemail.com  
right@example.com  
badlywrong.com  
whollycorrect@example.com  

删除元素后sn-p:

me@example.com  
you@example.com  
them@example.com  
incorrectemail.com  
new@example.com  
wrongemail.com  
right@example.com  
whollycorrect@example.com  

所以我很困惑为什么 'noemail.com''pretendemail.com''badlywrong.com' 被删除,而 'incorrectemail.com''wrongemail.com' 却没有。当文件中顺序有两封语法错误的电子邮件时,似乎会发生这种情况。

谁能指出我正确的方向?

【问题讨论】:

  • 啊,是的,它可能是重复的。我不知道我在找什么。谢谢巴尔加夫。

标签: python validation logic iteration dynamic-arrays


【解决方案1】:

这是因为您在迭代列表时要从列表中删除元素:

for i in target_email_list:
    if checkmailsyntax(i):
        target_email_list.remove(i) # here

因为,以下值是在一起的:

pretendemail.com  
wrongemail.com

一旦您删除pretendemail.com 电子邮件,下一个wrongemail.com 将向上移动,并且迭代器认为这已被迭代。所以接下来的项目是right@example.comwrongemail.com 永远不会检查有效的语法。您可以在检查语法之前添加print(i),然后自己查看。

您可以为此目的使用列表推导:

valid_emails = [email for email in target_email_list if checkmailsyntax(email)]

【讨论】:

  • 就这么简单。在当前代码中,valid_emails 给了我所有无效的;我通过从 checkmailsyntax 函数中删除 '==None' 对其进行了排序,以便在找到匹配项时返回 True。谢谢!
【解决方案2】:

AKS 的答案已涵盖:不要从您正在迭代的列表中删除!为了快速修复,您可以在迭代副本时从实际列表中删除:

for i in target_email_list[:]:  # iterates over the slice
    if checkmailsyntax(i):
        target_email_list.remove(i)  # removes from actual list

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-29
    • 2013-08-03
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2019-01-25
    相关资源
    最近更新 更多