我有一个这样的字符串列表:
samples = ['2345_234_1.0_1.35_001', '0345_123_2.09_1.3_003', ...]
列表可能很长(最坏情况下最多 10^6 个元素)。我有另一个包含一些子字符串的列表:
matches = ['7895_001', '3458_669', '0345_123', ...]
我想创建一个列表
matched_samples
,其中仅包含samples
的元素,其中包含matches
的一个或多个元素。例如,samples[1]
以 matched_samples
结束,因为 matches[3]
是 samples[1]
的子串。我可以做这样的事情:
matched_samples = [s for s in samples if any(xs in s for xs in matches)]
然而,这看起来像一个双循环,所以它不会很快。还有其他选择吗?如果
samples
是一个pandas
数据框,我可以简单地做:
matches_regex = '|'.join(matches)
matched_samples = samples[samples['sample'].str.contains(matches_regex)]
是否有类似的快速替代列表?
你可以做和你的熊猫例子一样的事情。
import re
samples = ['2345_234_1.0_1.35_001', '0345_123_2.09_1.3_003']
matches = ['7895_001', '3458_669', '0345_123']
pattern = re.compile(f"""{"|".join(re.escape(m) for m in matches)}""")
>>> [ s for s in samples if pattern.search(s) ]
['0345_123_2.09_1.3_003']
如果您的示例中没有换行符 - 您也可以将其转换为字符串并在模式周围使用
.findall()
和 (?:).*
。
不确定这是否会对速度产生影响。
>>> pattern = re.compile(f"""(?:{"|".join(re.escape(m) for m in matches)}).*""")
>>> pattern
re.compile(r'(?:7895_001|3458_669|0345_123).*', re.UNICODE)
>>> pattern.findall("\n".join(samples))
['0345_123_2.09_1.3_003']