【问题标题】:Python: Using list comprehensions to filter a list by a list of substringsPython:使用列表推导通过子字符串列表过滤列表
【发布时间】:2017-04-23 01:13:18
【问题描述】:

我认为这是一个简单的问题,所以我直接举个例子。

鉴于这两个列表:

x = ['a', 'ab', 'abc', 'bc', 'c', 'ac']
y = ['a', 'b']

我如何编写一个列表推导来过滤列表 x,结果是:

result = ['c']

我想要一个列表推导,排除 y 中的字符串与 x 中的字符串的任何部分匹配。例如,y 中的“a”将匹配 x 中的“a”、“ab”、“abc”和“ac”。

这种理解只匹配整个字符串:result = [r for r in x if r not in y]

如果已经有人问过这个问题,我很乐意接受指向先前答案的链接。也就是说,我还没有在 SO 上找到一个。

【问题讨论】:

    标签: python string list list-comprehension substring


    【解决方案1】:

    这取决于你的y 的长度最好的方法是什么,如果它包含很多元素,我会将它转换为一个集合并检查 x 中的任何项目是否与它有交集(一个公共字符) :

    y = set(y)
    [item for item in x if not y.intersection(item)]
    

    【讨论】:

    • 这假定y 仅包含长度为 1 的字符串,示例中就是这种情况,但未指定。
    • 是的,如果它包含更多字符,这肯定会失败,也许我从字面上理解了 OPs 的例子。但另一方面,如果y 仅包含单个字母,则速度要快得多。 :-)
    • 是的,在我的实际项目中,它被用于按子字符串过滤 url 列表。
    【解决方案2】:

    使用all:

    result = [r for r in x if all(z not in r for z in y)]
    

    any:

    result = [r for r in x if not any(z in r for z in y)]
    

    【讨论】:

      【解决方案3】:

      这是any 内置的工作。

      >>> x = ['a', 'ab', 'abc', 'bc', 'c', 'ac']
      >>> y = ['a', 'b']
      >>> [r for r in x if not any(s in r for s in y)]
      ['c']
      

      s in r 进行您想要的部分匹配,for s in y 检查y 的所有元素,如果有任何 匹配,any 为真。然后我们只是反转它。

      这是二次的,O(len(x) * len(y))。如果y 很长,合成一个正则表达式可能更高效:

      >>> import re
      >>> yy = re.compile("|".join(re.escape(s) for s in y))
      >>> [r for r in x if not yy.search(r)]
      ['c']
      

      其中应该只是 O(len(x) + len(y))。

      【讨论】:

        猜你喜欢
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 2018-02-12
        • 2020-08-28
        • 2017-05-10
        • 2019-11-18
        • 2022-01-16
        • 2011-06-17
        相关资源
        最近更新 更多