Python Find String in List: Methods and Examples

Jun 16, 2026 02:49 PM - 2 months ago 51515

Introduction

Finding a drawstring successful a database is 1 of the astir communal tasks successful Python. You mightiness do it to select log data, cheque personification input, look up configuration values, aliases activity done text. The quickest measurement to cheque if a drawstring is successful a database is the successful operator. It looks done the database 1 point astatine a clip and returns True aliases False:

my_list = ["apple", "banana", "cherry"] if "banana" in my_list: print("Found!")

Running this prints the pursuing output:

Output

Found!

That 1 statement answers the basal question, but existent codification often needs more. You mightiness request the index of a match, all the positions wherever it matches, a substring lucifer alternatively of an nonstop one, a case-insensitive search, aliases a pattern lucifer utilizing regular expressions.

This tutorial covers each attack pinch examples you tin run, compares their velocity and return types successful 1 table, and shows 3 real-world cases (filtering logs, checking input, and matching record paths) truthful you tin prime the correct method for what you need. Every illustration runs successful a modular Python 3.6+ situation (tested connected the latest unchangeable release, Python 3.14) and uses only the modular library, pinch nary other packages.

Key Takeaways

  • Use the successful usability ("target" successful my_list) for a fast, easy-to-read check; it returns True aliases False.
  • On a list, successful checks for an exact match, not a partial one. So "app" successful ["apple"] is False.
  • Use list.index("target") to get the position of the first match. Wrap it successful a try/except ValueError block, since it raises an correction erstwhile the drawstring is not there.
  • To find all matching positions, usage a database comprehension pinch enumerate(): [i for i, val successful enumerate(my_list) if val == "target"].
  • To cheque if immoderate constituent contains a substring, usage any("sub" successful point for point successful my_list). To cod those elements, usage a database comprehension.
  • Use next((item for point successful my_list if "sub" successful item), None) to get the first matching constituent (or a default) without checking the rest.
  • For case-insensitive matching, person some sides pinch .lower(), aliases usage re.search(pattern, item, re.IGNORECASE) for shape searches.
  • Checking rank successful a database is O(n) (it scans each item). If you hunt the aforesaid information galore times, person it to a group for O(1) mean lookups, arsenic noted successful the Python Wiki time-complexity reference.
  • Use regular expressions only erstwhile you are matching a pattern (dates, extensions, IDs). For fixed text, plain successful aliases str.find() is faster and easier to read.

Using the successful usability to cheque if a drawstring exists successful a list

The successful usability is the simplest and astir communal measurement to cheque whether a drawstring is successful a list, and it is the fastest prime for a one-time check. It returns True erstwhile a matching constituent exists and False erstwhile it does not. The matching not successful usability checks that a drawstring is missing.

l1 = ['A', 'B', 'C', 'D', 'A', 'A', 'C'] # Check whether a drawstring is coming successful the list if 'A' in l1: print('A is coming successful the list') # Check whether a drawstring is absent from the list if 'X' not in l1: print('X is not coming successful the list')

This produces the pursuing output:

Output

A is coming in the list X is not coming in the list

The aforesaid shape useful good for checking personification input. The pursuing illustration asks the personification for a worth and reports whether it appears successful the list:

l1 = ['A', 'B', 'C', 'D', 'A', 'A', 'C'] s = input('Please participate a characteristic A-Z:\n') if s in l1: print(f'{s} is coming successful the list') else: print(f'{s} is not coming successful the list')

If the personification types A, the programme prints:

Output

Please participate a characteristic A-Z: A A is coming in the list

One point to watch retired for: connected a list, successful checks for an exact match, not a partial one. "app" successful ["apple", "banana"] returns False because nary constituent equals "app", moreover though "apple" starts pinch it. If you request to lucifer a substring wrong database elements, spot the conception connected Searching for a substring wrong database elements. For much connected the drawstring formatting utilized here, spot f-strings successful Python.

Finding the scale of a drawstring pinch index()

When you request the position of a drawstring alternatively of a yes/no answer, usage the database index() method. It returns the scale of the first match, counting from zero.

my_list = ["apple", "banana", "cherry"] index = my_list.index("banana") print(index)

This returns the position of the first match:

Output

1

The consequence 1 intends "banana" is the 2nd element, since database indexes commencement astatine 0. The cardinal point to retrieve is that index() raises a ValueError if the worth is not there, truthful accumulation codification should wrap the telephone successful a try/except block:

my_list = ["apple", "banana", "cherry"] try: scale = my_list.index("mango") print(f"Found astatine scale {index}") except ValueError: print("Not found")

Because "mango" is absent, the isolated from branch runs and prints:

Output

Not found

Finding each indexes of a drawstring successful a list

The index() method only returns the first match. To get each position wherever a drawstring appears, harvester enumerate() pinch a database comprehension. This is simply a short, cleanable replacement for a manual while loop:

my_list = ["apple", "banana", "cherry", "banana"] indexes = [i for i, val in enumerate(my_list) if val == "banana"] print(indexes)

This returns a database of each matching indexes:

Output

[1, 3]

The comprehension checks each constituent and keeps the scale erstwhile it matches the target. Learn much successful the guides connected list comprehensions and enumerate().

Searching for a substring wrong database elements

A communal constituent of disorder is that successful connected a database checks for an nonstop match, erstwhile you whitethorn conscionable want to cognize whether immoderate constituent contains a target substring. The pursuing patterns lick this and fto you take the consequence you need: the matching elements, a True/False answer, aliases conscionable the first match.

Returning each elements that incorporate the substring

Use a database comprehension pinch the successful usability (which does cheque for substrings wrong individual strings) to cod each constituent that contains the target text:

my_list = ["apple", "banana", "cherry"] matches = [item for point in my_list if "an" in item] print(matches)

This keeps only the elements that incorporate "an":

Output

['banana']

Returning a boolean pinch any()

When you only request to cognize whether astatine slightest 1 constituent contains the substring, any() pinch a generator look is the astir businesslike choice, since it stops astatine the first match:

my_list = ["apple.log", "banana.txt", "cherry.csv"] has_log = any(".log" in point for point in my_list) print(has_log)

This reports whether immoderate constituent contains ".log":

Output

True

Returning the first lucifer pinch next()

If you want only the first matching constituent and thing else, next() complete a generator look returns it correct away. It besides takes a default value, which avoids a StopIteration correction erstwhile location is nary match:

my_list = ["app.log", "error.log", "data.csv"] first_error = next((item for point in my_list if "error" in item), None) print(first_error)

This returns the first constituent containing "error":

Output

error.log

Case-insensitive drawstring hunt successful a list

By default, each method supra is case-sensitive, truthful "BANANA" will not lucifer "banana". There are 2 reliable ways to make a hunt case-insensitive.

Normalizing pinch .lower()

The simplest attack is to person some the target and each constituent to the aforesaid lawsuit pinch .lower() (or .upper()) earlier you comparison them:

names = ["Alice", "BOB", "carol"] target = "bob" matches = [n for n in names if target.lower() in n.lower()] print(matches)

This matches "BOB" sloppy of case:

Output

['BOB']

Using re.IGNORECASE for shape searches

When your hunt uses a shape alternatively than a fixed string, walk the re.IGNORECASE emblem to re.search() wrong a comprehension. This is the cleaner prime erstwhile you besides request regular-expression features:

import re names = ["Alice", "BOB", "carol"] matches = [n for n in names if re.search("bob", n, re.IGNORECASE)] print(matches)

This returns the aforesaid case-insensitive result:

Output

['BOB']

Using regex to find strings successful a list

Regular expressions are the correct instrumentality erstwhile you are searching for a pattern (a date, a record extension, an ID format) alternatively than a fixed string. The re module from the modular room handles these searches. For an preamble to the syntax, spot An Introduction to Regular Expressions.

Filtering pinch re.search() and a database comprehension

re.search() returns a lucifer entity (which counts arsenic True) erstwhile the shape is recovered anyplace successful the string, and None otherwise. Combine it pinch a comprehension to select a list:

import re logs = ["2024-01-01 OK", "2024-01-02 ERROR", "no day here"] dated = [line for statement in logs if re.search(r"\d{4}-\d{2}-\d{2}", line)] print(dated)

This keeps only the lines that incorporate an ISO-style date:

Output

['2024-01-01 OK', '2024-01-02 ERROR']

Extracting matches pinch re.findall()

When you want the matched matter itself alternatively than the full element, re.findall() returns each lucifer of the shape successful a string. Use a comprehension to harvester the results crossed the database into 1 level list:

import re logs = ["2024-01-01 OK", "2024-01-02 ERROR", "no day here"] dates = [match for statement in logs for match in re.findall(r"\d{4}-\d{2}-\d{2}", line)] print(dates)

This collects the day strings themselves:

Output

['2024-01-01', '2024-01-02']

When to usage regex versus elemental drawstring methods

Use regex only erstwhile you genuinely request shape matching. For an nonstop match, usage the successful usability aliases index(). For a fixed substring, usage successful connected the constituent aliases str.find(). These plain methods are faster and overmuch easier to publication than a regular expression, and they debar hard-to-spot bugs caused by unescaped typical characters. Use regex erstwhile the target follows a elastic building (for example, matching immoderate .log aliases .txt extension, checking a day format, aliases pulling retired numeric IDs) and a plain drawstring cannot picture the rule.

Filtering a database by drawstring shape pinch database comprehension and filter()

Filtering a database down to the elements that lucifer a drawstring information is truthful communal that Python gives you 2 modular ways to do it. Both springiness the aforesaid result; the quality is mostly style.

Using a database comprehension

A database comprehension sounds people and is the astir communal prime among Python developers for filtering a list:

words = ["cat", "dog", "caterpillar", "cobra"] starts_with_cat = [w for w in words if w.startswith("cat")] print(starts_with_cat)

This keeps the words that commencement pinch "cat":

Output

['cat', 'caterpillar']

Using filter() pinch a lambda

The built-in filter() usability checks each constituent and returns an iterator, which you past move into a list:

words = ["cat", "dog", "caterpillar", "cobra"] starts_with_cat = list(filter(lambda w: w.startswith("cat"), words)) print(starts_with_cat)

This produces the identical result:

Output

['cat', 'caterpillar']

As a norm of thumb, usage the database comprehension successful astir cases because it is easier to read. filter() tin usage somewhat little representation for very ample inputs because it processes items only arsenic needed, and it sounds cleanly erstwhile you already person a named usability to walk alternatively of a lambda.

Counting occurrences pinch count()

When you request to cognize how galore times a drawstring appears alternatively than wherever it is, the database count() method returns the number of matches. A consequence of 0 intends the drawstring is not successful the list.

l1 = ['A', 'B', 'C', 'D', 'A', 'A', 'C'] s = 'A' count = l1.count(s) if count > 0: print(f'{s} is coming successful the database {count} times.')

This reports the wave of 'A':

Output

A is coming in the database 3 times.

Using a loop (alternative approach)

The built-in methods screen almost each case, but a plain loop is worthy knowing erstwhile you request to do other activity connected each constituent during the hunt aliases want much power complete really you loop done the list.

my_list = ["apple", "banana", "cherry", "banana"] found = False for point in my_list: if point == "banana": recovered = True break print(found)

This stops astatine the first lucifer and prints:

Output

True

This attack is longer and usually slower than the successful usability for elemental checks, truthful usage the built-in methods unless the loop assemblage does thing a comprehension cannot definitive cleanly.

Method comparison: which attack should you use?

Each method fits a different goal. The pursuing array matches communal usage cases to the recommended approach, what it returns, and its clip complexity. The complexity figures travel the charismatic Python Wiki time-complexity reference, wherever n is the number of elements successful the list.

Method Use case Returns Time complexity Notes
in operator Check if an nonstop constituent exists bool O(n) Most readable rank test; nonstop lucifer only
not successful operator Check that an constituent is absent bool O(n) Negative rank test
list.index() Position of the first nonstop match int (or ValueError) O(n) Wrap successful try/except ValueError
enumerate() + comprehension All positions of an nonstop match list[int] O(n) Returns each matching index
List comprehension pinch in All elements containing a substring list[str] O(n) Substring lucifer connected each element
any() Whether immoderate constituent contains a substring bool O(n) Short-circuits astatine the first match
next() First constituent containing a substring str (or default) O(n) Returns 1 match, past stops
count() Number of occurrences int O(n) 0 intends not present
re.search() successful comprehension Pattern-based filtering list[str] O(n * m) m is shape cost; usage only for patterns
set rank (in) Repeated exact-match lookups bool O(1) average No substring matching; build the group once

Handling ample datasets efficiently

When you activity pinch large datasets, the costs of an O(n) scan adds up if you hunt the aforesaid information galore times. A fewer changes to really you shop the information tin trim that costs a lot.

The astir effective alteration is to usage a group for repeated checks. Converting a database to a group pinch set(my_list) gives O(1) mean lookups alternatively of O(n), because sets usage hash tables alternatively of arrays. The trade-off is that sets do not support order, driblet duplicates, and cannot do substring matching, truthful they fresh exact-match checks alternatively than shape searches.

allowed = ["admin", "editor", "viewer", "guest"] allowed_set = set(allowed) print("editor" in allowed_set)

Because the lookup uses a hash table, this returns instantly moreover for very ample collections:

Output

True

Two much options are worthy knowing. Dictionaries springiness the aforesaid O(1) mean lookup arsenic sets, but they besides representation each cardinal to a value, which is perfect erstwhile you request other information and not conscionable a yes/no answer. For information that is already sorted, the modular room bisect module finds elements successful O(log n) clip utilizing binary search, which is faster than a afloat scan erstwhile you tin support the database successful order.

Real-world examples

The patterns supra are communal successful existent Python code. Here are 3 applicable examples of really you mightiness usage these drawstring hunt methods successful mundane tasks.

Filtering log lines that incorporate an correction string

Scanning logs for lines that mention an correction is simply a classical substring-filtering task, and a database comprehension solves it cleanly:

log_lines = [ "INFO startup complete", "ERROR database relationship failed", "WARNING disk almost full", "ERROR timeout while reference socket", ] errors = [line for statement in log_lines if "ERROR" in line] print(errors)

This isolates the 2 correction lines:

Output

['ERROR database relationship failed', 'ERROR timeout while reference socket']

Checking personification input against an allowed values list

Checking that a submitted worth is 1 of a known group is an exact-match check. Building a group first keeps the cheque accelerated moreover erstwhile you validate galore inputs:

allowed_roles = {"admin", "editor", "viewer"} submitted = "editor" if submitted in allowed_roles: print(f"{submitted} is simply a valid role") else: print(f"{submitted} is not allowed")

Because "editor" is successful the set, this prints:

Output

editor is simply a valid role

Extracting record paths that lucifer a pattern

Picking files by hold aliases naming normal is simply a occupation for regular expressions, since the target is simply a shape alternatively than a fixed string:

import re paths = ["report.csv", "image.png", "data.csv", "notes.txt"] csv_files = [p for p in paths if re.search(r"\.csv$", p)] print(csv_files)

This keeps only the paths ending successful .csv:

Output

['report.csv', 'data.csv']

FAQs

1. How to hunt a drawstring successful a database successful Python?

The fastest measurement to hunt for an nonstop drawstring is the successful operator, which returns True aliases False. Use it whenever you only request to cognize whether the drawstring is there:

my_list = ["apple", "banana", "cherry"] if "banana" in my_list: print("Found!")

If you request the position alternatively of a True/False answer, usage index() wrong a try/except artifact truthful a missing worth does not clang your program:

my_list = ["apple", "banana", "cherry"] try: scale = my_list.index("banana") print(f"Found astatine scale {index}") except ValueError: print("Not found")

2. How to cheque if a drawstring exists successful a database successful Python?

Use the successful operator, which is the modular measurement to cheque rank and returns True aliases False directly. It sounds almost for illustration plain English and is the champion default for a yes/no check:

my_list = ["apple", "banana", "cherry"] if "banana" in my_list: print("Exists") else: print("Does not exist")

3. How to find portion of a drawstring successful a list?

To find elements that contain a substring (rather than adjacent it exactly), usage a database comprehension pinch the successful operator, because successful checks for substrings wrong individual strings. This returns each constituent that contains the target text:

my_list = ["apple", "banana", "cherry"] part = "an" filtered_list = [item for point in my_list if portion in item] print(filtered_list) # ['banana']

For a elemental yes/no reply alternatively of the matching items, usage any(part successful point for point successful my_list).

4. How do I find a circumstantial drawstring successful Python?

To find a circumstantial drawstring and get its position, usage the index() method, which returns the scale of the first lucifer and raises ValueError if the drawstring is missing. Always wrap it successful try/except truthful a missing worth is handled gracefully:

my_list = ["apple", "banana", "cherry"] try: scale = my_list.index("banana") print(f"Found astatine scale {index}") except ValueError: print("Not found")

5. How to count occurrences of a drawstring successful a list?

Use the database count() method, which returns really galore times a worth appears. A return worth of 0 intends the drawstring is not successful the list:

my_list = ["apple", "banana", "cherry", "banana"] count = my_list.count("banana") print(f"Count: {count}") # 2

6. How to find each indexes of a drawstring successful a list?

Use a database comprehension pinch enumerate() to cod each scale wherever the drawstring appears, since index() returns only the first one. This gives you a database of each matching positions:

my_list = ["apple", "banana", "cherry", "banana"] indexes = [i for i, val in enumerate(my_list) if val == "banana"] print(indexes) # [1, 3]

7. How do I execute a case-insensitive drawstring hunt successful a Python list?

The simplest attack is to person some the target and each constituent to the aforesaid lawsuit pinch .lower() (or .upper()) earlier comparing them. This matches nary matter really the matter is capitalized:

items = ["Apple", "BANANA", "Cherry"] target = "banana" matches = [item for point in items if target.lower() in item.lower()] print(matches) # ['BANANA']

When the hunt uses a pattern, usage re.search("target", item, re.IGNORECASE) wrong a comprehension instead.

8. When should I usage regex to find strings successful a list?

Use regular expressions erstwhile the target is simply a pattern alternatively than fixed text, specified arsenic a day format, a record extension, aliases a system ID. For nonstop aliases elemental substring matching, the plain successful usability aliases str.find() is faster and easier to read:

import re files = ["a.log", "b.txt", "c.log"] logs = [f for f in files if re.search(r"\.log$", f)] print(logs) # ['a.log', 'c.log']

9. What is the clip complexity of uncovering a drawstring successful a Python list?

Methods that scan the full list, specified arsenic the successful operator, index(), count(), and database comprehensions, are O(n), which intends the costs grows pinch the magnitude of the list. If you request to tally galore checks connected the aforesaid data, person the database to a group erstwhile for O(1) mean lookups, arsenic documented successful the Python Wiki time-complexity reference. Keep successful mind that sets support only nonstop matching, not substring searches.

10. What is the quality betwixt list.index() and list.find() successful Python?

Python lists do not person a find() method, truthful calling my_list.find(...) raises an AttributeError. The find() method belongs to strings and returns -1 erstwhile the substring is missing. For lists, usage index() (which raises ValueError if the worth is missing) aliases a database comprehension erstwhile you request to find elements:

text = "banana" print(text.find("na")) # 2 (string method) fruits = ["apple", "banana"] print(fruits.index("banana")) # 1 (list method)

Conclusion

In this tutorial, you learned really to find a drawstring successful a Python database utilizing the correct instrumentality for each goal: the successful usability for accelerated rank checks, index() and enumerate() for positions, database comprehensions and any()/next() for substring searches, .lower() and re.IGNORECASE for case-insensitive matching, regular expressions for shape matching, and filter() arsenic an replacement to comprehensions. You besides saw really a group turns repeated O(n) scans into O(1) lookups, and really these patterns use to log filtering, input validation, and file-path matching.

For astir situations, the successful usability is the champion default. Use index() erstwhile you request a position, comprehensions erstwhile you request substring matches, and regular expressions only erstwhile you are matching a pattern.

Further reading

  • Understanding Lists successful Python 3
  • How To Use List Methods successful Python 3
  • Understanding List Comprehensions successful Python 3
  • An Introduction to Regular Expressions
  • How To Check If a String Contains Another String successful Python

Creative CommonsThis activity is licensed nether a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.

More