使用列表推导过滤字符串列表

6
>>> li = ["a b self", "mpilgrim", "foo c", "b", "c", "b", "d", "d"]
>>> condition = ["b", "c", "d"]
>>> [elem for elem in li if elem in condition]
['b', 'c', 'b', 'd', 'd']

但是是否有一种方法可以返回呢?
['a b self','foo c','b', 'c', 'b', 'd', 'd']

由于 b 和 c 都包含在 'a b self''foo c' 中,我希望代码也能返回这两个值。


如果 condition = ['d', 'e', 'f'],你会说 "e" 和 "f" 被 包含 在 "a b self" 和 "foo c" 中吗? - DSM
@DSM 不,我不会这样做,我只对空格之间的元素感兴趣。 - halo09876
你是否需要担心condition中的条目自带空格?例如,你是否需要查找"a b"并希望在"a b self"中找到它,但不在"a banana"中找到它? - DSM
不,这并不会成为问题。在您的例子中,我将寻找'a'和'b'在'a b self'以及'a'在'a bannana'中。条件中的元素没有空格,它们都是非空格字符串(即单个单词)。 - halo09876
谢谢,这意味着Elisha更新后的答案应该能对你起作用,我想。 - DSM
如果您正在寻找性能方面的问题,这个问题可能会引起您的兴趣。 - Eric Duminil
1个回答

5
假设代码需要检索包含任何条件字符串的所有字符串:
[elem for elem in li if any(c in elem for c in condition)]

如果需要完全匹配某个条件:

[elem for elem in li if
 any(re.search('(^|\s){}(\s|$)'.format(c), elem) for c in condition)]
编辑: 这可以简化为一个预定义的正则表达式:
predicate = re.compile('(^|\s)({})(\s|$)'.format('|'.join(condition)))

[elem for elem in li if predicate.search(elem)]

如果我们采用正则表达式的方式,我建议使用\b - DSM
2
我意识到这样会更精确: [elem for elem in li if any(c in elem.split() for c in condition)] - halo09876
@song0089,你说得对,分割方法更直接 :) - Elisha
需要使用split。此外,使用正则表达式联合比使用n个不同的正则表达式更好。 - Eric Duminil
或者 if set(elem.split()).intersection(condition)。但是这种方法不能很好地推广到条件中也可能有空格的情况(尽管 OP 对此并不感兴趣)。 - DSM
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接