for循环,而url.remove()仅影响其他所有条目

时间:2018-11-04 16:12:14

标签: python python-3.x list

在运行for循环并从列表中删除条目(清除无效的url)时出现一些令人困惑的行为:

urls = ['http://a.com/?mail=a@b.com','mailto:a@a.com', 'mailto:a@b.com', 'mailto:a@c.com', 'mailto:a@d.com']

for s in urls:
    if '@' in s and '?' not in s:
        urls.remove(s)

print(urls)

输出为:

['mailto:a@b.com', 'mailto:a@d.com']

这始终是其他所有条目,因此我假设我对python的理解不正确。

我研究了Python的列表理解,最后得出:

urls = [s for s in urls if not ('?' not in s and '@' in s)]

这就是我想要的。

那是最好的方法,有人可以解释一下这种行为,因为我不明白。

谢谢

2 个答案:

答案 0 :(得分:2)

第一个解决方案的问题是,您在从对象中删除条目的同时对其进行迭代。例如,在这里讨论该主题:How to remove items from a list while iterating?

答案 1 :(得分:0)

如果要在迭代过程中从列表中删除,请复制并进行迭代。 urls[:]获取urls的副本,然后对其进行迭代。这样可以避免在遍历原始列表时发生某些意外情况:

urls = ['http://a.com/?mail=a@b.com','mailto:a@a.com', 'mailto:a@b.com', 'mailto:a@c.com', 'mailto:a@d.com']

for s in urls[:]:
    if '@' in s and '?' not in s:
        urls.remove(s)

print(urls)

但是,我宁愿使用您的列表理解版本,它更简洁,更pythonic。