Reputation: 7
I am attempting to replace every other instance of the word "happy" in a file using python. Here is the input and expected output.
Input: "hello happy car happy dog happy lane happy"
Output: "hello happy car sad dog happy lane sad"
I am attempting to adjust the following code but having problems. Any suggestions are greatly appreciated.
def nth_repl_all(s, sub, repl, nth):
find = s.find(sub)
# loop util we find no match
i = 1
while find != -1:
# if i is equal to nth we found nth matches so replace
if i == nth:
s = s[:find]+repl+s[find + len(sub):]
i = 0
# find + len(sub) + 1 means we start after the last match
find = s.find(sub, find + len(sub) + 1)
i += 1
return s
Upvotes: 0
Views: 180
Reputation: 11496
You can use some approaches:
def replace(s):
# Count how many 'happy's are there
happy_count = s.count('happy')
# Create a list of words where every other word is 'sad'
words = ['sad' if i % 2 else 'happy' for i in range(happy_count)]
# Replace all 'happy's with the words to replace
return s.replace('happy', '{}').format(*words)
print(replace("hello happy car happy dog happy lane happy"))
# Output: hello happy car sad dog happy lane sad
itertools
:import itertools
def replace(s):
# Count how many 'happy's are there
happy_count = s.count('happy')
# Create a infinite generator of 'happy's and 'sad's
words = itertools.cycle(('happy', 'sad'))
# Take only the 'happy_count' first elements
words = itertools.islice(words, happy_count)
return s.replace('happy', '{}').format(*words)
print(replace("hello happy car happy dog happy lane happy"))
# Output: hello happy car sad dog happy lane sad
itertools
with list comprehensions:import itertools
def replace(s):
# Count how many 'happy's are there
happy_count = s.count('happy')
# Create a infinite generator of 'happy's and 'sad's
words = itertools.cycle(('happy', 'sad'))
# Get the next element of the generator 'happy_count' times
words = [next(words) for _ in range(happy_count)]
# Replace all 'happy's with the words to replace
return s.replace('happy', '{}').format(*words)
print(replace("hello happy car happy dog happy lane happy"))
# Output: hello happy car sad dog happy lane sad
Upvotes: 2
Reputation: 861
The initialization of i = 1
outside the loop and the resetting of i = 0
should be the same value.
Assuming nth = 2
means replace every other/second instance of the word, the value should be reset to i = 1
.
Currently, i = 0
means it will take two finds to increment i
to 2 and another find to replace the substring instance, for an incorrect total of 3 finds.
Upvotes: 0
Reputation: 781068
Split your string into words, then loop over that making the replacements.
def nth_replace_all(s, sub, repl, nth):
words = s.split()
i = 1
result = []
for word in words:
if word == sub:
if i == nth:
result.append(repl)
i = 1
else:
result.append(word)
i += 1
else:
result.append(word
return " ".join(result)
Upvotes: 0