如何检查一个字符串是否为字符串列表中某个字符串的子串

857

如何在以下列表中搜索包含字符串'abc'的项目?

xs = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
以下代码检查列表中是否存在'abc',但无法检测到'abc-123''abc-456':
if 'abc' in xs:

28
检查相反情况(如果一个字符串包含多个字符串中的任意一个):https://dev59.com/emw15IYBdhLWcg3wkMnz#6531704 - Antonio
如果条目的左侧部分是唯一的,请考虑从列表构建字典:基于部分字符串在列表中查找条目 - Georgy
请参考Raymond Hettinger的这个答案,它应该是这个问题的答案。 - mkrieger1
18个回答

1344

要在列表中的任何字符串中检查是否存在 'abc'

xs = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

if any("abc" in s for s in xs):
    ...

获取所有包含 'abc' 的项:

matching = [s for s in xs if "abc" in s]

8
获取包含子字符串 'abc' 的所有字符串的另一种方法:filter(lambda element: 'abc' in element, some_list) - floer32
但从可读性的角度来看,我更愿意将 any("abc" in s for s in some_list) 放在另一个函数中,并说 contains("abc",list) - Tarik
3
请使用index()方法:try: return mylist.index(myitem); except ValueError: pass - Sven Marnach
2
@midkin:我既不明白你到底想做什么,也不知道哪里出了问题。你最好通过“提问”按钮提出一个新问题,将你的代码、你期望代码执行的结果以及实际发生的情况复制进去。在这种情况下,“没有工作”是完全没有意义的,除非你定义了“工作”的含义,但即使如此,解释实际发生的情况比说出未发生的事情更好。 - Sven Marnach
1
@LarryCai 检查 "abc" in some_string 会检查 some_string 中是否存在完全一致、连续的子字符串 "abc",所以 "abc" in "cba-4123""abc" in "a-b-c" 都将返回 False。不需要对代码进行修改。 - Sven Marnach
显示剩余14条评论

234

我只是想提出一个想法:如果你需要匹配多个字符串,例如abcdef,你可以将两个推导式组合如下:

matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

输出:

['abc-123', 'def-456', 'abc-456']

27
这正是我在谷歌上搜索的内容,谢谢! - N8TRO
4
你也可以使用{s for s in my_list for xs in matchers if xs in s}(注意使用花括号来创建唯一的集合)。这种写法可能更易于阅读,但如果大多数s值都有匹配项,则速度可能会较慢,因为你的any函数会在第一个匹配项处高效停止。 - Matthias Fripp
2
惊人 - 在类似的情况下,我会使用pandas str.contains,但对于列表来说,这是完美的。 - data_runner
1
很好的解决方案。在我的情况下,我需要检查我的字符串(s)是否包含列表中所有子字符串(xs)(在这种情况下为“matchers”)。我只需将“any”更改为“all”,就可以解决问题: matching = [s for s in my_list if all(xs in s for xs in matchers)] - Dan

106

使用filter过滤得到所有包含'abc'的元素:

>>> xs = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> list(filter(lambda x: 'abc' in x, xs))
['abc-123', 'abc-456']

你也可以使用列表推导式:

>>> [x for x in xs if 'abc' in x]

101

如果你只需要知道'abc'是否在其中一个项目中,这是最短的方法:

if 'abc' in str(my_list):

注意:这假设“abc”是一个包含字母和数字的文本。如果“abc”可能只是特殊字符(例如[]'),请不要使用它。


2
如果你有一个列表["abc1", "1abc2"],那么这将会失败,因为它将会找到匹配,因为字符串'abc'将会在新创建的字符串中。 - cgseller
3
是的,这就是预期的行为...如果任何项包含“abc”,则返回true。 - RogerS
11
我不知道为什么其他人决定使用复杂的lambda解决方案,其实并没有必要!干得好@RogerS。 - ntk4
1
实际上,同样的问题几乎可以自己回答...我只是在它后面加了三个字母。 - RogerS
1
这是一个不错的解决方案,但如果你想找到包含给定字符串的项目,你将无法成功。在这里,你只能找到任何一个项目是否包含该字符串。 - cslotty
显示剩余7条评论

19

虽然这是一个比较旧的问题,但我提供这个答案是因为之前的答案无法处理列表中不是字符串或某种可迭代对象的项。这些项会导致整个列表推导式出现异常。

为了优雅地处理这样的列表项并跳过非可迭代项,请使用以下代码:

[el for el in lst if isinstance(el, collections.Iterable) and (st in el)]

接下来,拿到这样一个列表:

lst = [None, 'abc-123', 'def-456', 'ghi-789', 'abc-456', 123]
st = 'abc'

你仍将得到匹配的项目 (['abc-123', 'abc-456'])

这个可迭代性的测试可能不是最好的。从这里获取:在Python中,如何确定对象是否可迭代?


在给定的例子中,[el for el in lst if el and (st in el)] 不是更有意义吗? - Gordo
@tinix 我觉得它不会优雅地处理非可迭代对象,对吧? - Robert Muil
"给定示例"my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']不需要过于复杂化。 - Gordo
1
是的,绝对没错 - 接受的答案非常合适,我的建议更加复杂,所以请随意忽略它 - 我只是提供了一种可能性,以防有人遇到与我相同的问题:在这样的列表中,非可迭代项是现实中的可能性,尽管在给定的示例中不存在。 - Robert Muil

16
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

12
for item in my_list:
    if item.find("abc") != -1:
        print item

3
如果你想采取这种方式,我认为更习惯于使用if 'abc' in item而不是使用item.find('abc') == -1 - Wyatt Baldwin

10
any('abc' in item for item in mylist)

10

我是Python的新手。我让下面的代码运行起来并使它易于理解:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for item in my_list:
    if 'abc' in item:
       print(item)

6
使用Python字符串类的__contains__()方法。
a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")

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