检查Python列表项是否在另一个字符串中包含一个字符串


586

我有一个清单:

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

并要搜索包含字符串的项目'abc'。我怎样才能做到这一点?

if 'abc' in my_list:

会检查是否'abc'存在在列表中,但它的一部分'abc-123''abc-456''abc'对自己不存在。那么,如何获得包含的所有物品'abc'


19
要检查相反的内容(如果一个字符串包含多个字符串中的一个):stackoverflow.com/a/6531704/2436175
Antonio

如果条目的左侧部分是唯一的,请考虑从列表中构建一个字典:根据部分字符串
Georgy

Answers:


930

如果您只想检查abc列表中是否存在任何字符串,则可以尝试

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

如果您确实要获取包含的所有项目abc,请使用

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

我必须检查一项是否包含6个元素。做6个“如果”是否更快?还是一样?
奥利维尔·庞斯

41
@OlivierPons,就做if myitem in myarray:
alldayremix 2013年

8
另一种方式来获得一个包含所有子字符串“ABC”:filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k:使用index()方法:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach 2014年

1
@midkin:我既不了解您到底想做什么,也不知道它是怎么出错的。提出一个新问题(使用“问问题”按钮),复制您的确切代码,希望代码执行什么,以及实际执行什么操作,可能会给您带来更多的运气。除非您定义“有效”在这种情况下的含义,否则“无效”完全是没有意义的,但是即使那样,也要解释实际发生的情况而不是说没有发生的情况。
Sven Marnach

104

只是丢掉它:如果您碰巧需要与多个字符串匹配,例如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']

4
这正是我在谷歌上搜索的目的..谢谢!
N8TRO '16

2
您也可以使用{s for s in my_list for xs in matchers if xs in s}(请注意使用大括号创建唯一的集)。可能更容易阅读,但如果大多数s值都匹配,则可能会变慢,因为您any将有效地停在第一个匹配项上。
Matthias Fripp,

82

使用filter以获取该具备的要素abc

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

您还可以使用列表推导。

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

顺便说一句,不要将单词list用作变量名,因为它已经用于list类型。


50

如果您只想知道'abc'是否在其中一项中,这是最短的方法:

if 'abc' in str(my_list):

1
如果您有[“ abc1”,“ 1abc2”]的列表,则会失败,因为它会找到匹配项,因为字符串'abc'将在新创建的字符串中
cgseller

2
是的,这是预期的行为...如果任何一项包含“ abc”
则为

7
我不知道为什么所有这些其他人都决定在不需要时决定使用那些复杂的lambda解决方案!干得好@RogerS
ntk4

1
实际上,相同的问题几乎可以回答自己……我刚刚在上面添加了3个字母。
RogerS

1
这是一个很好的解决方案,但是如果您要查找包含给定字符串的项目,则不会成功。在这里,你看看任何的项目包含字符串。
cslotty

18

这是一个很老的问题,但是我提供这个答案,因为先前的答案不能解决列表中不是字符串(或某种可迭代对象)的项。这些项目将导致整个列表理解失败,并发生异常。

要通过跳过不可迭代的项目来优雅地处理列表中的此类项目,请使用以下命令:

[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我不是那样会优雅地处理不可迭代的对象吗?
罗伯特·穆伊

“给定的例子” my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] 无需过于复杂。
戈多

1
是的,绝对是-可接受的答案非常合适,我的建议更复杂,因此可以随意忽略它-我只是在万一有人遇到与我相同的问题时才提出:此类列表中的不可迭代项是现实世界中的可能性尽管在给定的示例中不存在。
罗伯特·穆伊

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

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

3
如果您要采用这种方法,我认为if 'abc' in item使用而不是习惯做法item.find('abc') == -1
Wyatt Baldwin


4

使用__contains__()Pythons字符串类的方法:

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")


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

for item in my_list:
    if (item.find('abc')) != -1:
        print ('Found at ', item)

0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)

在Python3.6中,这会产生错误:TypeError:预期的字符串或类似字节的对象
AimForClarity

1
@AimForClarity是的。python3.6中的re.findall需要一个字符串。另一种选择是将列表转换成字符串 import re mylist=['abc','def','ghi','abcff'] my_list_string=''.join(mylist) string_to_find="abc" res=re.findall(string_to_find,my_list_string) print(res)
arun_munagala

1
抱歉,格式化不正确。由于某些原因,无法进行适当的换行。
arun_munagala

0

我进行了搜索,要求您输入某个值,然后它将从包含您的输入的列表中查找一个值:

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

imp = raw_input('Search item: ')

for items in my_list:
    val = items
    if any(imp in val for items in my_list):
        print(items)

尝试搜索“ abc”。



0

我需要与匹配相对应的列表索引,如下所示:

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

[n for n, x in enumerate(lst) if 'abc' in x]

输出

[0, 3]

-1

问题:提供abc的信息

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


    aa = [ string for string in a if  "abc" in string]
    print(aa)

Output =>  ['abc-123', 'abc-456']

-2

据我所知,“ for”陈述总是会浪费时间。

当列表长度增加时,执行时间也会增加。

我认为,使用“ is”语句在字符串中搜索子字符串会更快一些。

In [1]: t = ["abc_%s" % number for number in range(10000)]

In [2]: %timeit any("9999" in string for string in t)
1000 loops, best of 3: 420 µs per loop

In [3]: %timeit "9999" in ",".join(t)
10000 loops, best of 3: 103 µs per loop

但是,我同意该any声明更具可读性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.