1

I am trying to create a program that replaces word from a string.

ColorPairs = {'red':'blue','blue':'red'}

def ColorSwap(text):
    for key in ColorPairs:
        text = text.replace(key, ColorPairs[key])
    print text

ColorSwap('The red and blue ball')
# 'The blue and blue ball'
instead of
# 'The blue and red ball'

This program replaces 'red' to 'blue', but not 'blue' to 'red'.I am stuck trying to figure out a way to make it so that the program doesn't override the first replaced key.

kidd
  • 29
  • 3
  • Do you only want the first replacement? Or do you want to make all replacements that don't undo an earlier replacement? – Dan Oberlam Mar 12 '15 at 03:59
  • unclear for me. Could you provide a long example along with expected output? – Avinash Raj Mar 12 '15 at 04:01
  • I voted to reopen, it seems that answers in suggested link offer variations of the OPs original idea, and do not answer the question. – Akavall Mar 12 '15 at 04:15
  • You could do this: 1) convert "red" to "999999" (some temp pattern), 2) convert "blue" to "red" 3) convert "999999" to "blue". – Akavall Mar 12 '15 at 04:20
  • I appreciate your help, but surely there must be a better way to do this? It would be a hassle if I want to expand my dictionary beside red and blue. – kidd Mar 12 '15 at 04:24
  • I think there has to be a better method as well, unfortunately I am not aware of it. That was just an idea. – Akavall Mar 12 '15 at 04:34
  • Thanks for your help anyway Akavall, I appreciate it! – kidd Mar 12 '15 at 04:43

3 Answers3

5

You could use re.sub function.

import re
ColorPairs = {'red':'blue','blue':'red'}
def ColorSwap(text):
    print(re.sub(r'\S+', lambda m: ColorPairs.get(m.group(), m.group()) , text))

ColorSwap('The blue red ball')

\S+ matches one or more non-space characters. You could use \w+ instead of \S+ also. Here for each single match, python would check for the match against the dictionary key. If there is a key like the match then it would replace the key in the string with the value of that particular key.

If there is no key found, it would display KeyError if you use ColorPairs[m.group()]. So that i used dict.get() method which returns a default value if there is no key found.

Output:

The red blue ball
Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • Thanks Avinash, but I don't quite understand what you're using there. Is it possible to do this without importing anything? I am very new at this and your code seems really complicated. Nevertheless I appreciate the help. – kidd Mar 12 '15 at 05:29
  • @Kidd see my answer if you don't want to import anything or if you don't want to use regex. – Heisenberg Mar 12 '15 at 06:49
  • 1
    @Avinash I liked your answer. Great ! – kvivek Mar 12 '15 at 07:00
  • 1
    Good answer. This has the advantage that it will work with any amount of inter-word whitespace, and will preserve that whitespace. – mhawke Mar 12 '15 at 11:27
0

Since the dictionary is unordered, So It may take blue converted to red in the first iteration and in the second iteration it change again from red to blue. So in order to get the result you need to code in this manner. This is certainly not the best Solution but an alternate way.

import re
def ColorSwap(text):
    text = re.sub('\sred\s',' blue_temp ', text)
    text = re.sub('\sblue\s', ' red_temp ', text)
    text = re.sub('_temp','', text)
    return text

print ColorSwap('The red and blue ball')
kvivek
  • 3,321
  • 1
  • 15
  • 17
  • 1
    @thefourtheye: It is certainly not the duplicate of multiple replacement. Please remove the tag of `marked as duplicate`. – kvivek Mar 12 '15 at 04:21
  • I still don't understand, this didn't fix anything. Please see my new edited post. sorry and thanks for helping me. – kidd Mar 12 '15 at 04:21
  • @kvivek Try "The blue red ball" as input and yes, this question is actually a duplicate of the question which I linked. Try the top voted answer in that question and the same can be used to solve this problem. – thefourtheye Mar 12 '15 at 05:26
0

If you don't want to use regex as suggested by @Avinash, you can split text into words, replace and then join.

ColorPairs = {'red':'blue','blue':'red'}
def ColorSwap(text):
    textList = text.split(' ')
    text = ' '.join(ColorPairs.get(k, k) for k in textList)
    print text

ColorSwap('The red and blue ball')

output

The blue and red ball
Heisenberg
  • 1,500
  • 3
  • 18
  • 35