【问题标题】:How to remove items from a list that contains words found in items in another list [duplicate]如何从包含在另一个列表中的项目中找到的单词的列表中删除项目[重复]
【发布时间】:2013-09-18 08:42:55
【问题描述】:

我想从列表“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']

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

谢谢。

【问题讨论】:

    标签: python list


    【解决方案1】:

    改用列表组合和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)]
    

    【讨论】:

    • 原始发布者的问题是在迭代列表时编辑列表。这不是避免这种情况的唯一方法,但它是一个很好的方法。
    【解决方案2】:

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

    通常在 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)
    

    【讨论】:

      【解决方案3】:
      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']
      

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

      【讨论】:

        【解决方案4】:

        当你遍历一个列表时,你永远不应该删除元素!那会打乱你的迭代。在 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] 中切换“六”和“五”的顺序,然后您的循环停止工作。那是因为它在字符串 '四六五' 中寻找字符串 '五六' 并且显然找不到它,因为该特定字符串没有完全匹配。

        现在,如果我们尝试将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']
        

        【讨论】:

          猜你喜欢
          • 2018-11-06
          • 1970-01-01
          • 2011-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-29
          • 1970-01-01
          相关资源
          最近更新 更多