2

I have a dictionary that looks like this:

result =  {'Mars': 1358996659, 'Snickers': 26100257, 'Ben%and%Jerry's': 102656, 'Tootsie%roll': 3825986}

I want to remove the '%' and replace it with a whitespace instead.

I've tried iterating over the list like so:

for key in result:
if "%" in key:
    key.replace("%"," ")
    print(key)

But it didn't work. I've also experimented with other loops, but nothing seems to work for me.

I would like to end up with a dictionary that looks like this:

result =  {'Mars': 1358996659, 'Snickers': 26100257, 'Ben and Jerry's': 102656, 'Tootsie roll': 3825986}
Micolho
  • 281
  • 2
  • 20
  • You have several good answers. But for future reference, remember that Python strings are immutable, thus string methods like `.replace` return a new string since they cannot affect the original. Also, there's no need to do the `if "%" in key` since `.replace` will do that test internally, and more efficiently. – PM 2Ring May 18 '18 at 11:15

3 Answers3

2

Use a dictionary comprehension to build a new dictionary, so you can replace the keys in one go:

result = {key.replace('%', ' '): value for key, value in result.items()}

The comprehension consists of:

  • an expression to generate a key, the part before the :
  • an expression to generate a value, the part after : but before the for
  • a for loop; you'll get as many key-value pairs as the for loop iterates (unless you add more for loops or if filters).

Your own solution didn't work, because str.replace() creates a new string object and returns that. The old string is never changed, because strings are immutable; they can't be altered in-place. If you wanted to do the work in a loop, you'd have to:

  • store the result of the str.replace() operation.
  • remove the old key (storing the value that it referenced temporarily)
  • add the new key to the dictionary, making it point to the value for the old key.

However, looping over a dictionary while mutating it (deleting and adding keys is mutating), is not safe and thus not supported. You'd have to loop over a copy of the keys; create one with list(result):

for key in list(result):
    if '%' in key:
        new_key = key.replace('%', ' ')
        value = result.pop(key)  # remove the old key, store the value
        result[new_key] = value

Re-generating the dictionary with a dictionary comprehension is just easier, at this point.

Note that in both approaches, you can end up with fewer keys if replacing '%' with ' ' leads to collisions! Which value remains after processing depends on which now-duplicate key was processed last.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0
  1. You can't change dictionary keys in place. You have to create a new dictionary, at least temporarily.
  2. This: key.replace("%"," ") doesn't do what you think it does. It doesn't change key, it returns a new value.

I had to fix your data, like this:

>>> result =  {'Mars': 1358996659, 'Snickers': 26100257, "Ben%and%Jerry's": 102656, 'Tootsie%roll': 3825986}

Then:

>>> result2 = {}
>>> for key, value in result.items():
        result2[key.replace("%"," ")] = value
>>> result2
{'Tootsie roll': 3825986, "Ben and Jerry's": 102656, 'Snickers': 26100257, 'Mars': 1358996659}
BoarGules
  • 16,440
  • 2
  • 27
  • 44
0

The code below will store the replaced key in a variable and you can add it to the dictionary, while removing the old key and value from the dictionary. The following code should give you the output that you are looking for:

result =  {'Mars': 1358996659, 'Snickers': 26100257, "Ben%and%Jerry's": 102656, 'Tootsie%roll': 3825986}

for key, value in result.items():
    if '%' in key:
       new_key = key.replace('%', ' ')
       del result[key]
       result[new_key] = value
print(result)

And here is your output:

{'Mars': 1358996659, 'Snickers': 26100257, "Ben and Jerry's": 102656, 'Tootsie roll': 3825986}
Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27