小能豆

检查字符串列表 A 中的任何项目是否是字符串列表 B 中项目的子字符串。

py

我正在尝试对一组匹配器和一组字符串进行排序,如果我有

matchers = ['foo', 'bar', 'abc']

strings = ['afooa', 'zbarz', 'abcabc', 'purple', 'foobar']

我希望能够获取strings其中任何元素都是子字符串的元素matchers,例如

results = ['afooa', 'zbarz', 'abcabc', 'foobar'],理想情况下不需要仅仅依靠嵌套的 for 循环。

我已经查看了一段时间,但是这个问题很难用可搜索的术语来表达,因此,任何人在搜索方面提供的任何建议都将不胜感激。


阅读 14

收藏
2024-11-17

共1个答案

小能豆

你可以使用 Python 中的列表解析或 filter 函数配合 any 来实现这个目标,而不需要明确地编写嵌套的 for 循环。

方法 1:列表解析

matchers = ['foo', 'bar', 'abc']
strings = ['afooa', 'zbarz', 'abcabc', 'purple', 'foobar']

# 使用列表解析和 any
results = [s for s in strings if any(m in s for m in matchers)]

print(results)

输出:

['afooa', 'zbarz', 'abcabc', 'foobar']

解析:

  1. any()any(m in s for m in matchers) 检查 matchers 中的任何一个子字符串是否存在于当前字符串 s 中。
  2. 列表解析:遍历 strings 中的每个字符串,筛选出满足条件的元素。

方法 2:使用 filter

results = list(filter(lambda s: any(m in s for m in matchers), strings))
print(results)

输出:

['afooa', 'zbarz', 'abcabc', 'foobar']

解析:

  • filter:对 strings 中的每个元素应用 lambda 函数,仅保留返回值为 True 的元素。
  • lambda:检查 matchers 中的任何一个子字符串是否存在于当前字符串中。

性能改进建议

如果 matchers 很大,可以将它转化为正则表达式进行匹配,进一步提高性能:

方法 3:使用正则表达式

import re

# 构建正则表达式模式
pattern = re.compile('|'.join(map(re.escape, matchers)))

# 筛选匹配的字符串
results = [s for s in strings if pattern.search(s)]

print(results)

输出:

['afooa', 'zbarz', 'abcabc', 'foobar']

解析:

  1. re.compile:将所有 matchers 合并成一个正则表达式模式,比如 foo|bar|abc
  2. re.escape:对特殊字符进行转义(防止误判)。
  3. pattern.search(s):检查 s 是否与模式匹配。

这三种方法都可以实现你的需求,根据数据规模选择适合你的实现方式即可!

2024-11-17