Nick
Nick

Reputation: 97

Encoder for a string - Python

I've been playing around with encoding random sets of strings using a dictionary. I've gotten my code to replace the letters I want, but in some cases it will replace a character more than once, when I truly only want it to replace the letter in the string once. This is what I have:

def encode(msg,code):
    for i in msg:
        for i in code:
            msg = msg.replace(i, code[i])
        return msg

for testing purposes I used the function calls: initial:

encode("blagh", {"a":"e","h":"r"})

and a more complex string:

encode("once upon a time",{'a':'ae','e':'ei','i':'io','o':'ou','u':'ua'})

for the second one right above, I'm looking for the output of : 'ouncei uapoun ae tiomei'

but instead am finding myself with :

"ounceio uapoun aeio tiomeio"

How can I limit my loop to only replacing each character once?

Upvotes: 2

Views: 340

Answers (2)

Mark Tolonen
Mark Tolonen

Reputation: 178021

Python 3's str.translate function does what you want. Note that the translation dictionary must use Unicode ordinals for keys, so the function uses a dictionary comprehension to convert it to the right format:

def encode(msg,code):
    code = {ord(k):v for k,v in code.items()}
    return msg.translate(code)

print(encode("blagh", {"a":"e","h":"r"}))
print(encode("once upon a time",{'a':'ae','e':'ei','i':'io','o':'ou','u':'ua'}))

Output:

blegr
ouncei uapoun ae tiomei

It works in Python 2 as well if you use Unicode strings or add the following to the top of the file to make strings Unicode by default:

from __future__ import unicode_literals

Upvotes: 2

falsetru
falsetru

Reputation: 369384

Instead of using str.replace, replace character by character:

def encode(msg, code):
    result = ''
    for ch in msg:
        result += code.get(ch, ch)
    return result

Using generator expression:

def encode(msg, code):
    return ''.join(code.get(ch, ch) for ch in msg)

Upvotes: 1

Related Questions