Home > Back-end >  Python - Trying to replace words in a list of strings but having problems with single letter words
Python - Trying to replace words in a list of strings but having problems with single letter words

Time:03-17

I have a list of strings such as words = ['Twinkle Twinkle', 'How I wonder'] I am trying to create a function that will find and replace words in the original list and I was able to do that except for when the user inputs single letter words such as 'I' or 'A' etc.

current function

def sub(old: string, new: string, words: list):
    words[:] = [w.replace(old, new) for w in words]

if input for old = 'I' and new = 'ASD'

current output = ['TwASDnkle TwASDnkle', 'How ASD wonder']

intended output = ['Twinkle Twinkle', 'How ASD wonder']

This is my first post here and I have only been learning python for a few months now so I would appreciate any help, thank you

CodePudding user response:

Don't use str.replace in a loop. This often doesn't do what is expected as it doesn't work on words but on all matches.

Instead, split the words, replace on match and join:

l = ['Twinkle Twinkle', 'How I wonder']

def sub(old: str, new: str, words: list):
    words[:] = [' '.join(new if w==old else w for w in x.split()) for x in words]
    
sub('I', 'ASD', l)

Output: ['Twinkle Twinkle', 'How ASD wonder']

Or use a regex with word boundaries:

import re

def sub(old, new, words):
    words[:] = [re.sub(fr'\b{re.escape(old)}\b', new, w) for w in words]
    
l = ['Twinkle Twinkle', 'How I wonder']
sub('I', 'ASD', l)
# ['Twinkle Twinkle', 'How ASD wonder']

NB. As @re-za pointed out, it might be a better practice to return a new list rather than mutating the input, just be aware of it

CodePudding user response:

It seems like you are replacing letters and not words. I recommend splitting sentences (strings) into words by splitting strings by the ' ' (space char).

output = []

I would first get each string from the list like this:

for string in words:

I would then split the strings into a list of words like this:

    temp_string = '' # a temp string we will use later to reconstruct the words
    for word in string.split(' '):

Then I would check to see if the word is the one we are looking for by comparing it to old, and replacing (if it matches) with new:

        if word == old: 
            temp_string  = new   ' '
        else:
            temp_string  = word   ' '

Now that we have each word reconstructed or replaced (if needed) back into a temp_string we can put all the temp_strings back into the array like this:

    output.append(temp_string[:-1]) # [:-1] means we omit the space at the end

It should finally look like this:

def sub(old: string, new: string, words: list):
    output = []
    for string in words:
        temp_string = '' # a temp string we will use later to reconstruct the words
        for word in string.split(' '):
            if word == old: 
                temp_string  = new   ' '
            else:
                temp_string  = word   ' '
        output.append(temp_string[:-1]) # [:-1] means we omit the space at the end
    return output
  • Related