Home > OS >  using loop to replace part of string with value from dict replaces it once but then reverts to origi
using loop to replace part of string with value from dict replaces it once but then reverts to origi

Time:02-04

I'm trying to replace a color spelled a specific way to a color that i can place on a map.

ive written this code after googling for a bit, thinking it will replace the color thats in the string with a color from the dict.

t = "Dark Blue Mountain"
dictcolors = {"Dark Green": "darkgreen", "Red": "red", "Dark Blue": "darkblue", "Blue": "blue", "Green":"green", "Orange": "orange", "Yellow": "yellow", "Gray" : "gray", "White":"white"}
for word, color in dictcolors.items():
    fixed_color = t.replace(word, color)
fixed_color

but it didnt work, it printed the original string: "Dark Blue Mountain".

I started looking for the error, as every possible site told me that it should work. I printed the replace part, to see what happened, and i got this:

Dark Blue
Dark Blue
darkblue
Dark blue
Dark Blue
Dark Blue
Dark Blue
Dark Blue
Dark Blue

as if it does replace it, but once it starts looking at the other colors it starts bugging out and reverts it. I of course expect it to print "darkblue" and thats it. can anyone help me fix this please?

CodePudding user response:

What you want is:

  • iterate over your color mapping
  • replace the part of the string
  • stop the looping And that's considering there is only a single "color" which should be replaced.
t = "Dark Blue Mountain"
dictcolors = {"Dark Green": "darkgreen", "Red": "red", "Dark Blue": "darkblue", "Blue": "blue", "Green":"green", "Orange": "orange", "Yellow": "yellow", "Gray" : "gray", "White":"white"}
for word, color in dictcolors.items():
    if word in t:
        fixed_t = t.replace(word, color)
        break

print(f"Fixed t: {fixed_t}, old t: {t}" 

Side notes:

If you printed the fixed_color in your code you'd see:

Dark Blue Mountain
Dark Blue Mountain
darkblue Mountain
Dark Blue Mountain
Dark Blue Mountain
Dark Blue Mountain
Dark Blue Mountain
Dark Blue Mountain
Dark Blue Mountain

and not the output you provided, because if the sub string is missing in the string to be replaced the original string is being returned, so it's expected behavior.

Naming matters, if not yet, it will in the future:

  • t is not a good name for a variable, try to find something more descriptive
  • word is not a good name neither, since it's multiple words, again think of better name
  • fixed_color is not a color, but a whole phrase

CodePudding user response:

The problem in your loop is that you are making the replacements on the original t variable at every iteration rather than use the string from the previous replacement. This effectively performs only the last replacement on t. You should initialize fixed_color with t before the loop and only work on that variable inside the loop (i.e. fixed_color = fixed_color.replace(...)

Alternatively, you could use a regular expression with the re.sub function:

import re

fixed_color = re.sub("|".join(dictcolors),lambda m:dictcolors[m[0]],t)

print(fixed_color)
# darkblue Mountain

The color names to replace are combined to form a search pattern (separated by pipes in accordance with regular expression operator syntax). The re.sub function allows use of a function (or lambda) to perform replacements which lets us refer back to the dictionary to get the normalized color names.

  • Related