Use the in operator:
if "blah" not in somestring:
continue
Note: This is case-sensitive.
Answer from Michael Mrozek on Stack OverflowUse the in operator:
if "blah" not in somestring:
continue
Note: This is case-sensitive.
You can use str.find:
s = "This be a string"
if s.find("is") == -1:
print("Not found")
else:
print("Found")
The
find()method should be used only if you need to know the position of sub. To check if sub is a substring or not, use theinoperator. (c) Python reference
What is the most efficient way to find substrings in strings?
How do I check if string contains all substrings in list?
You could try
if all([val in string for val in list]):
Which checks the truth of each check and returns True only if all are True. Otherwise you're looking at a loop (or if your lists get really big a generator).
Need to find a substring with wildcards in string
Loop through each sequential set of 5 characters and compute the hamming distance with your key string.
from itertools import tee, islice
def nwise(iterable, n=2):
"""s -> (s0, s1, ..., sn-1), (s1, s2, ..., sn), (s2, s3, ..., sn+1), ...
Comes from https://stackoverflow.com/a/21303303/5087436"""
iters = tee(iterable, n)
for i, it in enumerate(iters):
next(islice(it, i, i), None)
return zip(*iters)
def hamming_distance(s1, s2):
"""Returns the number of differences between s1 and s2 (assuming equal length)"""
return sum(c1 != c2 for c1, c2 in zip(s1, s2))
dna = "ABBACAGTABTAGAAGTBABGTABGTGABAATGBAAGTGBAATTGABAGGTAAGTBAGABAAABGTTAGAAG"
key = "AGTBA"
wildcards = 3
# for each substring with length the same as your key...
for i, seq in enumerate(nwise(dna, len(key))):
d = hamming_distance(seq, key)
if d <= wildcards:
print(f'DNA at index {i}', ''.join(seq), f'matches {key} with distance {d}.')
And this will output something like:
DNA at index 5 AGTAB matches AGTBA with distance 2.
DNA at index 8 ABTAG matches AGTBA with distance 3.
DNA at index 11 AGAAG matches AGTBA with distance 3.
DNA at index 14 AGTBA matches AGTBA with distance 0.
DNA at index 18 ABGTA matches AGTBA with distance 3.
DNA at index 19 BGTAB matches AGTBA with distance 3.
DNA at index 23 BGTGA matches AGTBA with distance 2.
DNA at index 25 TGABA matches AGTBA with distance 2.
DNA at index 29 AATGB matches AGTBA with distance 3.
DNA at index 30 ATGBA matches AGTBA with distance 2.
DNA at index 31 TGBAA matches AGTBA with distance 3.
DNA at index 35 AGTGB matches AGTBA with distance 2.
DNA at index 36 GTGBA matches AGTBA with distance 3.
DNA at index 37 TGBAA matches AGTBA with distance 3.
DNA at index 40 AATTG matches AGTBA with distance 3.
DNA at index 41 ATTGA matches AGTBA with distance 2.
DNA at index 43 TGABA matches AGTBA with distance 2.
DNA at index 47 AGGTA matches AGTBA with distance 2.
DNA at index 48 GGTAA matches AGTBA with distance 2.
DNA at index 52 AGTBA matches AGTBA with distance 0.
DNA at index 56 AGABA matches AGTBA with distance 1.
DNA at index 58 ABAAA matches AGTBA with distance 3.
DNA at index 60 AAABG matches AGTBA with distance 3.
DNA at index 63 BGTTA matches AGTBA with distance 2.
DNA at index 67 AGAAG matches AGTBA with distance 3.
You could also like, sort by the hamming distance and stuff if you wanted too by using it as a key function. This should all be super efficient since it's using iterators and only loops through your key string once per iteration; so it's an O(m*n) operation where m and n are the lengths of your key string and DNA string.
Here's slightly more betterer code IMO (not sure what info is most important, so this has all the major parts); basically, we just add a namedtuple for each match to get better string representation and all the info we could want about any match:
from itertools import tee, islice
from collections import namedtuple
Match = namedtuple('Match', 'start, stop, distance, substring, key, wildcards')
def nwise(iterable, n=2):
iters = tee(iterable, n)
for i, it in enumerate(iters):
next(islice(it, i, i), None)
return zip(*iters)
def hamming_distance(s1, s2):
s = sum(c1 != c2 for c1, c2 in zip(s1, s2))
d = ''.join('*' if c1 != c2 else c1 for c1, c2 in zip(s1, s2))
return s, d
def findmatches(string, key, nwildcards):
n = len(key)
for i, seq in enumerate(nwise(string, n)):
dist, diffs = hamming_distance(seq, key)
if dist <= nwildcards:
yield Match(i, i+n, dist, ''.join(seq), key, diffs)
dna = "ABBACAGTABTAGAAGTBABGTABGTGABAATGBAAGTGBAATTGABAGGTAAGTBAGABAAABGTTAGAAG"
key = "AGTBA"
nwildcards = 3
for m in findmatches(dna, key, nwildcards):
print(m)
And this would produce output like:
Match(start=5, stop=10, distance=2, substring='AGTAB', key='AGTBA', wildcards='AGT**')More on reddit.com
Match(start=8, stop=13, distance=3, substring='ABTAG', key='AGTBA', wildcards='A*T**')
Match(start=11, stop=16, distance=3, substring='AGAAG', key='AGTBA', wildcards='AG***')
Match(start=14, stop=19, distance=0, substring='AGTBA', key='AGTBA', wildcards='AGTBA')
Match(start=18, stop=23, distance=3, substring='ABGTA', key='AGTBA', wildcards='A***A')
Match(start=19, stop=24, distance=3, substring='BGTAB', key='AGTBA', wildcards='*GT**')
Match(start=23, stop=28, distance=2, substring='BGTGA', key='AGTBA', wildcards='*GT*A')
Match(start=25, stop=30, distance=2, substring='TGABA', key='AGTBA', wildcards='*G*BA')
Match(start=29, stop=34, distance=3, substring='AATGB', key='AGTBA', wildcards='A*T**')
Match(start=30, stop=35, distance=2, substring='ATGBA', key='AGTBA', wildcards='A**BA')
Match(start=31, stop=36, distance=3, substring='TGBAA', key='AGTBA', wildcards='*G**A')
Match(start=35, stop=40, distance=2, substring='AGTGB', key='AGTBA', wildcards='AGT**')
Match(start=36, stop=41, distance=3, substring='GTGBA', key='AGTBA', wildcards='***BA')
Match(start=37, stop=42, distance=3, substring='TGBAA', key='AGTBA', wildcards='*G**A')
Match(start=40, stop=45, distance=3, substring='AATTG', key='AGTBA', wildcards='A*T**')
Match(start=41, stop=46, distance=2, substring='ATTGA', key='AGTBA', wildcards='A*T*A')
Match(start=43, stop=48, distance=2, substring='TGABA', key='AGTBA', wildcards='*G*BA')
Match(start=47, stop=52, distance=2, substring='AGGTA', key='AGTBA', wildcards='AG**A')
Match(start=48, stop=53, distance=2, substring='GGTAA', key='AGTBA', wildcards='*GT*A')
Match(start=52, stop=57, distance=0, substring='AGTBA', key='AGTBA', wildcards='AGTBA')
Match(start=56, stop=61, distance=1, substring='AGABA', key='AGTBA', wildcards='AG*BA')
Match(start=58, stop=63, distance=3, substring='ABAAA', key='AGTBA', wildcards='A***A')
Match(start=60, stop=65, distance=3, substring='AAABG', key='AGTBA', wildcards='A**B*')
Match(start=63, stop=68, distance=2, substring='BGTTA', key='AGTBA', wildcards='*GT*A')
Match(start=67, stop=72, distance=3, substring='AGAAG', key='AGTBA', wildcards='AG***')
Regex that matches a pattern anywhere in a string
Videos
Hello,
There are several ways to find substrings in string, You could use substring in string you could use string.index(substring), or you could use string.find(substring) or even use regex.
I'm trying to understand if there is a significant difference between them for my use case, which is finding people names in article titles for example:
I want to check if Leonardo DiCaprio is in Leonardo DiCaprio gets called out for boarding superyacht: ‘eco-hypocrite’
What I usually do is:
def is_substring_in_string(substring: str, string: str):
#same thing as before but on the article title.
string_alphanumeric = ''.join(e for e in string if e.isalnum()).lower()
return substring in string_alphanumeric
def main():
names = ["Harrison Ford","Leonardo DiCaprio","Eddie Murphy","Bruce Willis","Will Smith"]
#removes unwanted charecters such as !@#$%^&*() etc and converts to lower case
names_alnum_lower = [''.join(e for e in x if e.isalnum()).lower() for x in names]
article_title = "Leonardo DiCaprio gets called out for boarding superyacht: eco-hypocrite"
for idx, lower_name in enumerate(names_alnum_lower):
if is_substring_in_string(lower_name,article_title):
print(f"Actor Name: '{names[idx]}' is in article title '{article_title}'")
if __name__ == '__main__':
main()Imagine there are a bunch of articles and people's names. Is this method acceptable or will I be better off using regex or something else?