0

Here's my problem.

    sentence = "This car is awsome."

and what I want do do is

    sentence.replace("a","<emoji:a>")
    sentence.replace("b","<emoji:b>")
    sentence.replace("c","<emoji:c>")

and so on...

But of course if I do it in that way the letters in "<emoji:>" will also be replaced as I go along. So how can I do it in other way?

Carlos Gonzalez
  • 858
  • 13
  • 23

2 Answers2

2

As Carlos Gonzalez suggested:

create a mapping dict and apply it to each character in sequence:

sentence = "This car is awsome."

# mapping
up = {"a":"<emoji:a>",
      "b":"<emoji:b>",
      "c":"<emoji:c>",}

# apply mapping to create a new text (use up[k] if present else default to k)
text = ''.join( (up.get(k,k) for k in sentence) )

print(text)

Output:

This <emoji:c><emoji:a>r is <emoji:a>wsome.

The advantage of the generator expression inside the ''.join( ... generator ...) is that it takes each single character of sentence and either keeps it or replaces it. It only ever touches each char once, so there is no danger of multiple substitutions and it takes only one pass of sentence to convert the whole thing.

Doku: dict.get(key,default) and Why dict.get(key) instead of dict[key]?


If you used

sentence = sentence.replace("a","o")
sentence = sentence.replace("o","k")

you would first make o from a and then make k from any o (or a before) - and you would have to touch each character twice to make it happen.

Using

up = { "a":"o", "o":"k" }
text = ''.join( (up.get(k,k) for k in sentence) )

avoids this.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • You can easily fool this code by adding `"e":""` to `up`... I think that's the main point of the question to begin with. – norok2 Oct 05 '18 at 11:19
  • 1
    @norok2 did you try it out? You could fool it if you replaced one after another - but the list comp doesn't. It works on every single character of `sentence` and creates an itermediary generator that either keeps the character or replaces it. the generator is then stick together again. nothing gets processed multiple times. - if you appended to `up` as suggested, the `text` would be `This r is wsom` – Patrick Artner Oct 05 '18 at 12:09
  • You are right. I read it too quickly. But the this trick would not work for multi-char replacements, right? – norok2 Oct 05 '18 at 13:46
  • @norok2 if you want to replace more then 1 char it is easier to do this using regex and sub - see [passing a function to re.sub in python](https://stackoverflow.com/questions/18737863/passing-a-function-to-re-sub-in-python) - but thats needs the `re` module as import and is not needed in this case - see the 2nd answer I posted. – Patrick Artner Oct 05 '18 at 15:58
1

If you want to replace more then 1 character at a time, it would be easier to do this with regex. Inspired by Passing a function to re.sub in Python

import re 

sentence = "This car is awsome."

up = {"is":"Yippi",
      "ws":"WhatNot",}

# modified it to create the groups using the dicts key
text2 = re.sub( "("+'|'.join(up)+")", lambda x: up[x.group()], sentence)

print(text2)

Output:

ThYippi car Yippi aWhatNotome.

Doku: re.sub(pattern, repl, string, count=0, flags=0)

You would have to take extra care with your keys, if you wanted to use "regex" specific characters that have another meaning if used as regex-pattern - f.e. .+*?()[]^$

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69