161

Background:

Example list: mylist = ['abc123', 'def456', 'ghi789']

I want to retrieve an element if there's a match for a substring, like abc

Code:

sub = 'abc'
print any(sub in mystring for mystring in mylist)

above prints True if any of the elements in the list contain the pattern.

I would like to print the element which matches the substring. So if I'm checking 'abc' I only want to print 'abc123' from list.

6
  • 10
    You probably don't want to name a variable list, since that's the name of a built in data type (and you won't be able to do list(x) in the future) Commented Dec 8, 2012 at 16:50
  • Try filter. Should do what you need. Example here stackoverflow.com/questions/3640359/… Commented Dec 8, 2012 at 16:52
  • @DavidRobinson it's just for the example Commented Dec 8, 2012 at 17:02
  • 1
    "it will print True for every element in the list." You are confused; it will print True only once, because any returns a single boolean value. It means exactly what it says: it returns a boolean that indicates if any of the listed things are true. Commented Dec 8, 2012 at 18:50
  • I'm not confused. That was the output, so I must've made a mistake in using any because it printed True for every element in the list. Commented Dec 8, 2012 at 19:51

5 Answers 5

199
print [s for s in list if sub in s]

If you want them separated by newlines:

print "\n".join(s for s in list if sub in s)

Full example, with case insensitivity:

mylist = ['abc123', 'def456', 'ghi789', 'ABC987', 'aBc654']
sub = 'abc'

print "\n".join(s for s in mylist if sub.lower() in s.lower())
Sign up to request clarification or add additional context in comments.

9 Comments

I think you should encourage use of generators when possible, such as in your second example :)
for case insensitivity use sub.lower() in s (thank you stackoverflow.com/questions/3627784/case-insensitive-in-python)
@mattwilkie Note that to be case insensitive you'd need sub.lower() in s.lower(), or it won't work when s is not lowercase.
oh. yes, thanks for catching that! The function I've been working passed my prototype data but would have failed on the real thing next week. (added example, remove if you don't like it)
mind to explain what is the reasoning behind s for s in list if sub in s ? what does it even mean
|
87

All the answers work but they always traverse the whole list. If I understand your question, you only need the first match. So you don't have to consider the rest of the list if you found your first match:

mylist = ['abc123', 'def456', 'ghi789']
sub = 'abc'
next((s for s in mylist if sub in s), None) # returns 'abc123'

If the match is at the end of the list or for very small lists, it doesn't make a difference, but consider this example:

import timeit

mylist = ['abc123'] + ['xyz123']*1000
sub = 'abc'

timeit.timeit('[s for s in mylist if sub in s]', setup='from __main__ import mylist, sub', number=100000)
# for me 7.949463844299316 with Python 2.7, 8.568840944994008 with Python 3.4
timeit.timeit('next((s for s in mylist if sub in s), None)', setup='from __main__ import mylist, sub', number=100000) 
# for me 0.12696599960327148 with Python 2.7, 0.09955992100003641 with Python 3.4

4 Comments

Really great solution, by the way. I used it in some recent code.
That's a good point, thumbs up for you!
this is an interesting solution but if you put ['abc123'] at the end of your "mylist" your solution will still take a very long time.
@Angelo Agree. The only reason this goes so fast is because it finds the match in the first element. So the time taken for this example is the BEST case. WORST case is it takes just as long (if it's not in the list). Still a good solution.
28

Use a simple for loop:

seq = ['abc123', 'def456', 'ghi789']
sub = 'abc'

for text in seq:
    if sub in text:
        print(text)

yields

abc123

Comments

14

This prints all elements that contain sub:

for s in filter (lambda x: sub in x, list): print (s)

Comments

13

I'd just use a simple regex, you can do something like this

import re
old_list = ['abc123', 'def456', 'ghi789']
new_list = [x for x in old_list if re.search('abc', x)]
for item in new_list:
    print item

2 Comments

Why add complexity? The in operator is perfect for the job as seen in other responses. Regexes are a great tool, but I think it's a bit overkill here.
Very nifty piece of code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.