7

我想从列表“a”中删除项目,其中列表“b”包含在列表“a”中找到的单词

a = ['one two three', 'four five six', 'seven eight nine']
b = ['two', 'five six']

结果应该是:

a = ['seven eight nine']

这是因为在列表“a”中的项目中可以找到“二”和“五六”这两个词。

这就是我试图解决它的方式:

for i in a:
    for x in b:
        if x in i:
            a.remove(i)

这将返回:

print a
['four five six', 'seven eight nine']

为什么这不起作用,我该如何解决这个问题?

谢谢。

4

4 回答 4

8

列表在被迭代时不应该被修改。这样做可能会产生不良的副作用,例如循环跳过项目。

通常在 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)
于 2013-09-13T15:37:27.290 回答
6

使用列表组合,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)]
于 2013-09-13T15:36:09.427 回答
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']

此外,在你的开场问题中,你说你想用文字比较。您当前的循环不会这样做。考虑一下,当您遍历 listb时,您实际上是在尝试查看两个单词的字符串是否是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]你的循环停止工作。那是因为它在字符串“四六五”中寻找字符串“五六”,显然找不到它,因为该特定字符串没有完全匹配。

现在,如果我们尝试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']
于 2013-09-13T15:43:50.680 回答
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']

您必须从最后开始浏览您的列表,否则项目会重新排序。

于 2013-09-13T15:39:05.673 回答