892

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
  • 28
    To check the opposite (if one string contains one among multiple strings): stackoverflow.com/a/6531704/2436175 Commented Nov 18, 2014 at 10:48
  • If the left parts of entries are unique, consider constructing a dict from the list: Find an entry in a list based on a partial string Commented Feb 6, 2019 at 10:19
  • See also this answer by Raymond Hettinger (which should rather be an answer to this question). Commented Aug 11, 2021 at 9:38

17 Answers 17

1388

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]
Sign up to request clarification or add additional context in comments.

20 Comments

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?
Another way to get all strings containing substring 'abc': filter(lambda element: 'abc' in element, some_list)
@p014k: use the index() method: try: return mylist.index(myitem); except ValueError: pass
@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.
@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.
|
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 Comments

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.
AMAZING - in a similar situation I would use pandas str.contains, but with lists this is perfect
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)]
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]

Comments

105

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 Comments

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
Yes, this is the intended behaviour... true if any of the items contain 'abc'
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
Actually the same question almost answers itself... I just added 3 letters to it.
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.
|
21

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 Comments

Wouldn't [el for el in lst if el and (st in el)] make more sense in the given example?
@tinix I don't that will handle non-iterable objects gracefully, will it?
"given example" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] no need to over complicate it.
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.
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.
16
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

Comments

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

1 Comment

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.
10
any('abc' in item for item in mylist)

Comments

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)

Comments

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")

Comments

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]

Comments

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']

Comments

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

pattern=re.compile(r'abc') 

pattern.findall(mylist)

3 Comments

In Python3.6 this gives an error: TypeError: expected string or bytes-like object
@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)
Sorry for the poor formatting. Couldnt do proper line breaks for some reason.
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])

Comments

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)

Comments

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'.

Comments

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?")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.