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 OverflowHelp with .index()? finding multiple instances of item
How do I replace a string at multiple indices (Python)? - Stack Overflow
python - How do I get the index of multiple occurrences of the same character in a string? - Stack Overflow
Get multiple strings from array indices - PYTHON - Stack Overflow
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.
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
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
I must say your code is a bit clunky and hard to understand.
But if you want to apply the same operation to a list of indices, then just iterate over your list of indices and apply the same logic:
pos_list = [i for i in range(len(string)) if string[i] == userinput]
for pos in pos_list:
word = word[:pos] + 'X' + word[pos + 1:]
You could simply iterate over the array:
while True:
userinput = input("Give me a letter\n").upper()
if len(userinput) == 1:
if userinput in string:
pos = [i for i in range(len(string)) if string[i] == userinput]
for p in pos:
secretword = secretword[:p] + userinput + secretword[p+1:]
print(secretword)
You can try join(), I hope this is the solution you are looking for
myArray = ["this ","is ","a ","test.","this ","is ","another ","test."]
print(' '.join(myArray[:4]))
print(' '.join(myArray[4:]))
It seems like what you actually want is to join together some sublist in your list of words.
>>> myArray = ["this ","is ","a ","test.","this ","is ","another ","test."]
>>> print(''.join(myArray[0:4]))
this is a test.
>>> print(''.join(myArray[4:8]))
this is another test.
Create a new str to avoid change the main_str:
main_str = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
indexes_list = [
{
"type": "first_type",
"startOffset": 0,
"endOffset": 5,
},
{
"type": "second_type",
"startOffset": 16,
"endOffset": 22,
}
]
new_str = ""
index = 0
for i in indexes_list:
start = i["startOffset"]
end = i["endOffset"]
new_str += main_str[index: start] + "<span>" + main_str[start:end] + "</span>"
index = end
new_str += main_str[index:]
print(new_str)
Here is a solution without any imperative for loops. It still uses plenty of looping for the list comprehensions.
# Get all the indices and label them as starts or ends.
starts = [(o['startOffset'], True) for o in indexes_list]
ends = [(o['endOffset'], False) for o in indexes_list]
# Sort everything...
all_indices = sorted(starts + ends)
# ...so it is possible zip together adjacent pairs and extract substrings.
pieces = [
(s[1], main_str[s[0]:e[0]])
for s, e in zip(all_indices, all_indices[1:])
]
# And then join all the pieces together with a bit of conditional formatting.
formatted = ''.join([
f"<span>{part}</span>" if is_start else part
for is_start, part in pieces
])
formatted
# '<span>Lorem</span> Ipsum is s<span>imply </span>dummy text of the printing and typesetting industry.'
Also, although you said you do not want for loops, it is important to note that you do not have to do any index modification if you do the updates in reverse order.
def update_str(s, spans):
for lookup in sorted(spans, reverse=True, key=lambda o: o['startOffset']):
start = lookup['startOffset']
end = lookup['endOffset']
before, span, after = s[:start], s[start:end], s[end:]
s = f'{before}<span>{span}</span>{after}'
return s
update_str(main_str, indexes_list)
# '<span>Lorem</span> Ipsum is s<span>imply </span>dummy text of the printing and typesetting industry.'
s = 'long string that I want to split up'
indices = [0,5,12,17]
parts = [s[i:j] for i,j in zip(indices, indices[1:]+[None])]
returns
['long ', 'string ', 'that ', 'I want to split up']
which you can print using:
print '\n'.join(parts)
Another possibility (without copying indices) would be:
s = 'long string that I want to split up'
indices = [0,5,12,17]
indices.append(None)
parts = [s[indices[i]:indices[i+1]] for i in xrange(len(indices)-1)]
Here is a short solution with heavy usage of the itertools module. The tee function is used to iterate pairwise over the indices. See the Recipe section in the module for more help.
>>> from itertools import tee, izip_longest
>>> s = 'long string that I want to split up'
>>> indices = [0,5,12,17]
>>> start, end = tee(indices)
>>> next(end)
0
>>> [s[i:j] for i,j in izip_longest(start, end)]
['long ', 'string ', 'that ', 'I want to split up']
Edit: This is a version that does not copy the indices list, so it should be faster.
It seems that you're trying to find occurrences of a word inside a string: the re library has a function called finditer that is ideal for this purpose. We can use this along with a list comprehension to make a list of the indexes of a word:
>>> import re
>>> word = "foo"
>>> string = "Bar foo lorem foo ipsum"
>>> [x.start() for x in re.finditer(word, string)]
[4, 14]
This function will find matches even if the word is inside another, like this:
>>> [x.start() for x in re.finditer("foo", "Lorem ipsum foobar")]
[12]
If you don't want this, encase your word inside a regular expression like this:
[x.start() for x in re.finditer("\s+" + word + "\s+", string)]
Probably not the fastest/best way but it will work. Used in rather than == in case there were quotations or other unexpected punctuation aswell! Hope this helps!!
def getWord(string, word):
index = 0
data = []
for i in string.split(' '):
if i.lower() in word.lower():
data.append(index)
index += 1
return data
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")
You could potentially use โcompress()โ from Itertools to create a binary filter.
Compress takes two arguments
The iterable that you want to go over and โpunchโ out characters
The data which defines which elements from the first iterable are removed. Any โTrueโ element will enable compress to remove the element from the first iterable

If I'm reading what you want to do correctly, a function like this could work.
def punch(str, mask):
if (len(str) == len(mask)):
new_list = []
for i in range(len(str)):
if mask[i] == "1":
new_list.append(str[i])
return new_list
else:
return -1