我想从列表'a'中删除项目,其中列表'b'包含在列表'a'中找到单词的项目
a = ['one two three', 'four five six', 'seven eight nine']
b = ['two', 'five six']
结果应为:
a = ['seven eight nine']
这是因为在'a'列表中的项目中可以找到单词'two'和'five six'。
这就是我试图解决的问题:
for i in a:
for x in b:
if x in i:
a.remove(i)
返回:
print a
['four five six', 'seven eight nine']
为什么这不起作用,我该如何解决这个问题?
感谢。
答案 0 :(得分:5)
使用列表comp和any
代替:
a = ['one two three', 'four five six', 'seven eight nine']
b = ['two', 'five six']
print [el for el in a if not any(ignore in el for ignore in b)]
答案 1 :(得分:3)
在迭代过程中不应修改列表。这样做会产生不良副作用,例如跳过项目的循环。
通常在Python中,您应该避免一次一个地添加和删除列表中的元素的循环。通常这些类型的循环可以用更惯用的列表推导来替换。
[sa for sa in a if not any(sb in sa for sb in b)]
对于它的价值,修复循环的一种方法是迭代列表的副本,这样循环不受原始变化的影响。
for i in a[:]:
for x in b:
if x in i:
a.remove(i)
答案 2 :(得分:3)
当你遍历列表时,你永远不应该删除元素!那会弄乱你的迭代。在Python中迭代列表时干净地编辑列表的唯一方法是在列表的长度上向后迭代并删除元素。
例如,这可以作为一个有效的就地删除循环:
a = ['one two three', 'four five six', 'seven eight nine']
b = ['two', 'five six']
for i in range(len(a) - 1, -1, -1):
for x in b:
if x in a[i]:
del a[i]
print a # prints ['seven eight nine']
此外,在您的开场问题中,您说您想要通过单词进行比较。你当前的循环不会这样做。考虑一下,当你循环遍历列表b
时,你实际上会尝试查看双字符串是否是a
中某个项的子字符串。您不希望将双字串一起使用。您希望将字符串拆分为单独的单词元素。为此,split()
功能是关键。
请注意,以下代码不会删除列表中的第二个元素:
a = ['one two three', 'four six five', 'seven eight nine']
b = ['two', 'five six']
for i in range(len(a) - 1, -1, -1):
for x in b:
if x in a[i]:
del a[i]
print a # prints ['four six five', 'seven eight nine']
我所做的就是在a[1]
中切换'六'和'五'的顺序,你的循环停止工作。那是因为它在字符串'four six five'中寻找字符串'five six'并且显然找不到它,因为该特定字符串没有完全匹配。
现在,如果我们尝试将split
字符串翻译成单词,我们可以通过迭代单词列表来实际进行检查。
a = ['one two three', 'four six five', 'seven eight nine']
b = ['two', 'five six']
for i in range(len(a) - 1, -1, -1):
for x in b:
for word in x.split():
if word in a[i]:
del a[i]
print a # correctly prints ['seven eight nine']
答案 3 :(得分:0)
for i in reversed(range(len(a))):
for j in reversed(range(len(b))):
if b[j] in a[i]:
a.remove(a[i])
# output = ['seven eight nine']
您必须从最后查看列表,否则项目会重新排序。