Using regular expressions, you can use re.finditer to find all (non-overlapping) occurences:
>>> import re
>>> text = 'Allowed Hello Hollow'
>>> for m in re.finditer('ll', text):
print('ll found', m.start(), m.end())
ll found 1 3
ll found 10 12
ll found 16 18
Alternatively, if you don't want the overhead of regular expressions, you can also repeatedly use str.find to get the next index:
>>> text = 'Allowed Hello Hollow'
>>> index = 0
>>> while index < len(text):
index = text.find('ll', index)
if index == -1:
break
print('ll found at', index)
index += 2 # +2 because len('ll') == 2
ll found at 1
ll found at 10
ll found at 16
This also works for lists and other sequences.
Answer from poke on Stack OverflowUsing regular expressions, you can use re.finditer to find all (non-overlapping) occurences:
>>> import re
>>> text = 'Allowed Hello Hollow'
>>> for m in re.finditer('ll', text):
print('ll found', m.start(), m.end())
ll found 1 3
ll found 10 12
ll found 16 18
Alternatively, if you don't want the overhead of regular expressions, you can also repeatedly use str.find to get the next index:
>>> text = 'Allowed Hello Hollow'
>>> index = 0
>>> while index < len(text):
index = text.find('ll', index)
if index == -1:
break
print('ll found at', index)
index += 2 # +2 because len('ll') == 2
ll found at 1
ll found at 10
ll found at 16
This also works for lists and other sequences.
I think what you are looking for is string.count
"Allowed Hello Hollow".count('ll')
>>> 3
Hope this helps
NOTE: this only captures non-overlapping occurences
How can I find all indices where a substring appears in a string?
Help with .index()? finding multiple instances of item
python - Find a substring in a string and returning the index of the substring - Stack Overflow
python - Function to find all occurrences of substring - Code Review Stack Exchange
Videos
There is no simple built-in string function that does what you're looking for, but you could use the more powerful regular expressions:
import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]
If you want to find overlapping matches, lookahead will do that:
[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]
If you want a reverse find-all without overlaps, you can combine positive and negative lookahead into an expression like this:
search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]
re.finditer returns a generator, so you could change the [] in the above to () to get a generator instead of a list which will be more efficient if you're only iterating through the results once.
>>> help(str.find)
Help on method_descriptor:
find(...)
S.find(sub [,start [,end]]) -> int
Thus, we can build it ourselves:
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
list(find_all('spam spam spam spam', 'spam')) # [0, 5, 10, 15]
No temporary strings or regexes required.
Taken from https://www.programiz.com/python-programming/online-compiler/?ref=409055e9 :
vowels = ['a', 'e', 'i', 'o', 'i', 'u']
# index of the first 'i' is returned
index = vowels.index('i')
print('The index of i:', index)
Output: The index of i: 2
Say that the list was much bigger, and you don't know the contents, but you know 'i' is in it more than once. What would be the best way to find all instances of 'i'?
Thanks so much! <3
There's a builtin method find on string objects.
s = "Happy Birthday"
s2 = "py"
print(s.find(s2))
Python is a "batteries included language" there's code written to do most of what you want already (whatever you want).. unless this is homework :)
find returns -1 if the string cannot be found.
Ideally you would use str.find or str.index like demented hedgehog said. But you said you can't ...
Your problem is your code searches only for the first character of your search string which(the first one) is at index 2.
You are basically saying if char[0] is in s, increment index until ch == char[0] which returned 3 when I tested it but it was still wrong. Here's a way to do it.
def find_str(s, char):
index = 0
if char in s:
c = char[0]
for ch in s:
if ch == c:
if s[index:index+len(char)] == char:
return index
index += 1
return -1
print(find_str("Happy birthday", "py"))
print(find_str("Happy birthday", "rth"))
print(find_str("Happy birthday", "rh"))
It produced the following output:
3
8
-1
I would turn this function into a generator so that an iteration over its values does not unnecessarily build a list into memory. If the caller trully needs a list, they can still call list(find_substring(...)). I would also rename this function substring_indexes as I feel it better convey what this function is about; also index could be something like last_known_position or last_found. But naming is hard and I might be wrong on this one.
def substring_indexes(substring, string):
"""
Generate indices of where substring begins in string
>>> list(find_substring('me', "The cat says meow, meow"))
[13, 19]
"""
last_found = -1 # Begin at -1 so the next position to search from is 0
while True:
# Find next index of substring, by starting after its last known position
last_found = string.find(substring, last_found + 1)
if last_found == -1:
break # All occurrences have been found
yield last_found
The example in the docstring should illustrate that the returned indexes may overlap, since that is not apparent from the function name, and since other find_all functions behave differently.
Also, don't mix single and double quotes unless you have good reason. The example should therefore be
substring_indexes("ana", "Canadian banana")
I'm doing MOOC Python 2023 and I need to return all substrings of a string. An example of what the code should do is this:
Please type in a word: mammoth
Please type in a character: m
mam
mmo
mot
My code is this:
word = input("Please type in a word: ")
char = input("Please type in a character: ")
iterate = 1
while True:
index = word.find(char)
third = index + 3
string = word[index:third]
if len(string) != 3:
break
else:
print(string)
word = word[iterate:]
iterate += 1It works for the word "mammoth", but not for other words. Like when I put in the word "incomprehensibility" and search for character "i", I get this output:
inc
ibi
ibi
ibi
ibi
ity
Any help is appreciated