在有效性检查后从python中的列表中删除项目

时间:2016-05-24 16:26:57

标签: python validation logic iteration dynamic-arrays

背景:

我正在编写一个小脚本,作为其中一个参数,需要一个文件中的电子邮件地址列表。该脚本将继续通过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)

检查我在删除元素代码段之前和之后放入的代码时出错,看看它是否在执行它的工作:

for i in target_email_list:
    print i

问题:代码的输出是:

删除元素片段之前(以及提交文件的全部内容):

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  

删除元素代码段后:

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'却没有。当文件中依次存在两个语法错误的电子邮件时,似乎会发生这种情况。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

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

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)]

答案 1 :(得分:0)

AKS的答案包括你:不要从列表中删除你正在迭代!对于快速修复,您可以在迭代副本时从实际列表中删除:

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