878

How do I search for items that contain the string 'abc' in the following list?

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

The following checks if 'abc' is in the list, but does not detect 'abc-123' and 'abc-456':

if 'abc' in xs:
3

17 Answers 17

1370

To check for the presence of 'abc' in any string in the list:

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

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

To get all the items containing 'abc':

matching = [s for s in xs if "abc" in s]
19
  • I have to check if one item is in an array of 6 elements. Is it quicker to do 6 "if" or is it the same? Commented Mar 10, 2013 at 0:11
  • 9
    Another way to get all strings containing substring 'abc': filter(lambda element: 'abc' in element, some_list)
    – floer32
    Commented May 31, 2013 at 20:10
  • 3
    @p014k: use the index() method: try: return mylist.index(myitem); except ValueError: pass Commented Oct 16, 2014 at 12:02
  • 2
    @midkin: I neither understand what exactly you were trying to do, nor how it went wrong. You'll probably have more luck by asking a new question (with the "Ask Question" button), copying your exact code, what you would have expected the code to do, and what it actually did. "Did not work" is completely meaningless unless you define what "works" means in this context, but even then it's better to explain what actually happened instead of saying what didn't. Commented Feb 16, 2015 at 13:11
  • 1
    @LarryCai The check "abc" in some_string will check for presence of "abc" as an exact, contiguous substring of some_string, so both "abc" in "cba-4123" and "abc" in "a-b-c" will return False. No modification of the code required. Commented Sep 13, 2021 at 9:12
238

Just throwing this out there: if you happen to need to match against more than one string, for example abc and def, you can combine two comprehensions as follows:

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

Output:

['abc-123', 'def-456', 'abc-456']
3
  • 4
    You could also use {s for s in my_list for xs in matchers if xs in s} (note the curly brackets to create a unique set). Might be easier to read, but could be slower if most s values will have a match, since your any will efficiently stop at the first match. Commented Jan 9, 2018 at 18:47
  • 3
    AMAZING - in a similar situation I would use pandas str.contains, but with lists this is perfect Commented Apr 20, 2022 at 6:50
  • 1
    Great, solution. In my case I needed to check if my string (s) had ALL the substrings (xs) from a list (in this case matchers). I just changed any for all and it did the trick: matching = [s for s in my_list if all(xs in s for xs in matchers)]
    – Dan
    Commented Jan 16, 2023 at 22:07
107

Use filter to get all the elements that have 'abc':

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

One can also use a list comprehension:

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

If you just need to know if 'abc' is in one of the items, this is the shortest way:

if 'abc' in str(my_list):

Note: this assumes 'abc' is an alphanumeric text. Do not use it if 'abc' could be just a special character (i.e. []', ).

12
  • 4
    This would fail if you had a list of ["abc1", "1abc2"] as it would find a match because the string 'abc' would be in the newly created string
    – cgseller
    Commented Jan 26, 2017 at 13:20
  • 3
    Yes, this is the intended behaviour... true if any of the items contain 'abc'
    – RogerS
    Commented Jan 29, 2017 at 19:39
  • 12
    I don't know why all these other people decide to do those convoluted lambda solutions when they don't need to! Nice job @RogerS
    – ntk4
    Commented Sep 14, 2017 at 5:30
  • 1
    Actually the same question almost answers itself... I just added 3 letters to it.
    – RogerS
    Commented Sep 15, 2017 at 13:32
  • 2
    It's a nice solution, but if you want to find the items which contain the given string, you will not succeed. Here you find out if any of the items contains the string.
    – cslotty
    Commented May 9, 2019 at 9:03
20

This is quite an old question, but I offer this answer because the previous answers do not cope with items in the list that are not strings (or some kind of iterable object). Such items would cause the entire list comprehension to fail with an exception.

To gracefully deal with such items in the list by skipping the non-iterable items, use the following:

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

then, with such a list:

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

you will still get the matching items (['abc-123', 'abc-456'])

The test for iterable may not be the best. Got it from here: In Python, how do I determine if an object is iterable?

5
  • Wouldn't [el for el in lst if el and (st in el)] make more sense in the given example?
    – Gordo
    Commented Oct 1, 2016 at 6:20
  • @tinix I don't that will handle non-iterable objects gracefully, will it? Commented Oct 17, 2016 at 8:31
  • "given example" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] no need to over complicate it.
    – Gordo
    Commented Oct 17, 2016 at 20:15
  • 1
    Yes absolutely - the accepted answer is perfectly suitable and my suggestion is more complicated, so feel free to ignore it - I just offered in case someone had the same problem as I had: non-iterable items in such lists are a real-world possibility despite not existing in the given example. Commented Oct 18, 2016 at 18:28
  • While it is over-engineered for the question, it does make the function far more general - which itself is great if one wishes to re-use for multiple uses in the codebase.
    – Konchog
    Commented Jun 25 at 8:54
16
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]
0
12
for item in my_list:
    if item.find("abc") != -1:
        print item
1
  • 3
    If you're going to take this approach, I think it's more idiomatic to do if 'abc' in item rather using item.find('abc') == -1. Commented Mar 10, 2016 at 22:22
10
any('abc' in item for item in mylist)
10

I am new to Python. I got the code below working and made it easy to understand:

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

Use the __contains__() method of Pythons string class.:

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

I needed the list indices that correspond to a match as follows:

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

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

output

[0, 3]
3

If you want to get list of data for multiple substrings

you can change it this way

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
# select element where "abc" or "ghi" is included
find_1 = "abc"
find_2 = "ghi"
result = [element for element in some_list if find_1 in element or find_2 in element] 
# Output ['abc-123', 'ghi-789', 'abc-456']
1
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)
3
  • In Python3.6 this gives an error: TypeError: expected string or bytes-like object Commented Aug 13, 2018 at 21:41
  • 3
    @AimForClarity Yes. re.findall in python3.6 expects a string. An alternative would be by converting the list into a string 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) Commented Aug 14, 2018 at 12:32
  • 1
    Sorry for the poor formatting. Couldnt do proper line breaks for some reason. Commented Aug 14, 2018 at 12:36
1

Adding nan to list, and the below works for me:

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456',np.nan]
any([i for i in [x for x in some_list if str(x) != 'nan'] if "abc" in i])
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

I did a search, which requires you to input a certain value, then it will look for a value from the list which contains your input:

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)

Try searching for 'abc'.

0
def find_dog(new_ls):
    splt = new_ls.split()
    if 'dog' in splt:
        print("True")
    else:
        print('False')


find_dog("Is there a dog here?")

Not the answer you're looking for? Browse other questions tagged or ask your own question.