Replace string in list then join list to form new string

Question:

I have a project where I need to do the following:

  • User inputs a sentence
  • intersect sentence with list for matching strings
  • replace one of the matching strings with a new string
  • print the original sentence featuring the replacement
fruits = ['Quince', 'Raisins', 'Raspberries', 'Rhubarb', 'Strawberries', 'Tangelo', 'Tangerines']
#   Asks the user for a sentence.
random_sentence = str(input('Please enter a random sentence:n')).title()
stripped_sentence = random_sentence.strip(',.!?')
split_sentence = stripped_sentence.split()
#   Solve for single word fruit names
sentence_intersection = set(fruits).intersection(split_sentence)
#   Finds and replaces at least one instance of a fruit in the sentence with “Brussels Sprouts”.
intersection_as_list = list(sentence_intersection)
intersection_as_list[-1] = 'Brussels Sprouts'

Example Input: "I would like some raisins and strawberries."

Expected Output: "I would like some raisins and Brussels Sprouts."

But I can’t figure out how to join the string back together after making the replacement. Any help is appreciated!

Asked By: Luna5225

||

Answers:

You can do it with a regex:

(?i)Quince|Raisins|Raspberries|Rhubarb|Strawberries|Tangelo|Tangerines

This pattern will match any of your words in a case insensitive way (?i).

In Python, you can obtain that pattern by joining your fruits into a single string. Then you can use the re.sub function to replace your first matching word with "Brussels Sprouts".

import re 

fruits = ['Quince', 'Raisins', 'Raspberries', 'Rhubarb', 'Strawberries', 'Tangelo', 'Tangerines']

#   Asks the user for a sentence.
#random_sentence = str(input('Please enter a random sentence:n')).title()
sentence = "I would like some raisins and strawberries."

pattern = '(?i)' + '|'.join(fruits)
replacement = 'Brussels Sprouts'

print(re.sub(pattern, replacement, sentence, 1))

Output:

I would like some Brussels Sprouts and strawberries.

Check the Python demo here.

Answered By: lemon

Create a set of lowercase possible word matches, then use a replacement function.

If a word is found, clear the set, so replacement works only once.

import re

fruits = ['Quince', 'Raisins', 'Raspberries', 'Rhubarb', 'Strawberries', 'Tangelo', 'Tangerines']
fruit_set = {x.lower() for x in fruits}

s =  "I would like some raisins and strawberries."
def repfunc(m):
    w = m.group(1)
    if w.lower() in fruit_set:
        fruit_set.clear()
        return "Brussel Sprouts"
    else:
        return w

print(re.sub(r"(w+)",repfunc,s))

prints:

I would like some Brussel Sprouts and strawberries.

That method has the advantage of being O(1) on lookup. If there are a lot of possible words it will beat the linear search that | performs when testing word after word.

It’s simpler to replace just the first occurrence, but replacing the last occurrence, or a random occurrence is also doable. First you have to count how many fruits are in the sentence, then decide which replacement is effective in a second pass.

like this: (not very beautiful, using a lot of globals and all)

total = 0
def countfunc(m):
    global total
    w = m.group(1)
    if w.lower() in fruit_set:
        total += 1

idx = 0
def repfunc(m):
    global idx
    w = m.group(1)
    if w.lower() in fruit_set:
        if total == idx+1:
            return "Brussel Sprouts"
        else:
            idx += 1
            return w
    else:
        return w

re.sub(r"(w+)",countfunc,s)

print(re.sub(r"(w+)",repfunc,s))

first sub just counts how many fruits would match, then the second function replaces only when the counter matches. Here last occurrence is selected.

Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.