I’m trying to code a function that takes a sentence and a phrase as parameter and eliminates all but the first instance of the phrase in the sentence.
Note, by sentence I mean a string comprised of one or more words, not a list of words.
At present my code is as follows:
def delete_repeated_phrase(sentence, phrase):
# first count the number of instances of a phrase in the sentence, if no occurences, return the original sentence
if sentence.count(phrase) == 0:
return sentence
# get phrase length
phrase_len = len(phrase)
# reverse the string because we want to remove the phrase from end of sentence to start of sentence
reversed_sentence = "".join(reversed(sentence))
reversed_phrase = "".join(reversed(phrase))
# while there remains more than 1 instance of phrase in sentence
while reversed_sentence.count(reversed_phrase) > 1:
#slice string to remove the first occurence ogf the phrase
index = reversed_sentence.find(reversed_phrase)
if index == 0:
reversed_sentence = reversed_sentence[phrase_len + 1:]
else:
reversed_sentence = reversed_sentence[0:index] + reversed_sentence[index + 1 + phrase_len:]
sentence = "".join(reversed(reversed_sentence))
return sentence
Usage:
the_sentence = ‘the cat the cat the cat the cat the cat the cat the cat’
seek_phrase = ‘the cat’
print(f’{delete_repeated_phrase( the_sentence, seek_phrase)}')
When I originally posted I missed the fact it was doing exactly what I intended - removing all but one instance of the phrase.
Having said that I’ve still learned a good few things from this post and the replies that have followed, so thanks to everyone that has responded.
I assume that you split the sentence of SPACE.
That means you have a list of words.
E.g [‘a’, ‘test’, ‘of’, ‘my’, ‘code’]
When you look for the phrase ”my code” it contains a SPACE.
But the list has that as two elements not one.
Removing from the end is a good idea, but works better for items from lists you iterate over.
You want to remove all occurrences of phrase except for the first one. That means that after you’ve found the first occurence you can remove all other occurrences.
You know that you can find in a string from a specific starting point, right?
So str.find() does correctly find substrings that include spaces within another string. That being the case I’m struggling to see why my code isn’t finding and eliminating substrings containing spaces.
In a generalised case I want to solve two problems (with two different functions).
remove all but the first occurence of a phrase within a sentence
remove only the last occurence of a phrase within a sentence
in both cases accepting that the phrase my be ‘a string of words’ or a ‘[bracketed string of words that_may_or_may_not_contain_spaces-or-other-delimiters]’
Yip I get that, however I just realised my own stupidity. The code is written so as to eliminate all but the first instance of phrase, hence it returning the original string because it contains only one instance of the phrase. In other words, it’s working as intended. Doh! Sorry for wasting everyone’s time.
Looking more closely at the code, given there can never be > 1 instance if str.find() returns 0, that part of the code is redundant and could be revised as:
def delete_repeated_phrase(sentence, phrase):
# first count the number of instances of a phrase in the sentence, if no occurences, return the original sentence
if sentence.count(phrase) == 0:
return sentence
# get phrase length
phrase_len = len(phrase)
# reverse the string because we want to remove the phrase from end of sentence to start of sentence
reversed_sentence = "".join(reversed(sentence))
reversed_phrase = "".join(reversed(phrase))
# while there remains more than 1 instance of phrase in sentence
while reversed_sentence.count(reversed_phrase) > 1:
#slice string to remove the first occurence of the phrase
index = reversed_sentence.find(reversed_phrase)
reversed_sentence = reversed_sentence[0:index] + reversed_sentence[index + 1 + phrase_len:]
new_sentence = "".join(reversed(reversed_sentence))
return new_sentence
Where did you learn to reverse a string like that? That’s very inefficient. Better use sentence[::-1] like everybody else.
That’s also misleading, I thought sentence was a list or so based on that code. You really should add a usage example in the first post, not just later.
I am on Mobile right now, so I can’t write the code right, but a way shorter and faster solution is going to be to not reverse the string at all. Just find the first match, and use replace with a start parameter to replace all later matches with the empty string.
If you want to code the algorithm I described, go ahead. I am not going to do that till I get back home. “Mobile” is in fact a summary of multiple reasons why I am not going to code it right now.
when removing all but the first instance of the phrase, does removing happen after preserving the first instance, or does one remove and then the first instance gets preserved (whole)?