BotZakk
BotZakk

Reputation: 39

Translate table value error ValueError: string keys in translate table must be of length 1

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import os, sys

test = input()
translation = {

    "hi":"jk" , "as":"bc" , "ca":"sa"
}

translated = test.maketrans(translation)
print(test.translate(translated))

Result

Traceback (most recent call last):
  File "C:/Users/DELL/PycharmProjects/untitled1/Inpage.py", line 11, in <module>
    translated = test.maketrans(translation)
ValueError: string keys in translate table must be of length 1

Don't mind the imports and magic comments. The program is utf-8 related and is not important to this current problem. Anyone has a workaround or some way to fix this, I'll be happy. And the table is 47 translations long.

Upvotes: 3

Views: 3903

Answers (1)

Nelly Mincheva
Nelly Mincheva

Reputation: 470

Not allowing keys of length greater than 1 has its intentions behind it. For example if you have two translation keys - "ca" and "c" which one is prioritized?

I don't know your specific use case but lets suppose you have ordered the translation map in your order of interest (most commonly I think you will want it sorted by length, smallest to largest).

Then you can implement the following:

import re

def custom_make_translation(text, translation):
    regex = re.compile('|'.join(map(re.escape, translation)))
    return regex.sub(lambda match: translation[match.group(0)], text)

Note that with the given implementation this

translation = {
    "hi":"jk", 
    "as":"bc", 
    "ca":"sa",
    "c": "oh no, this is not prioritized"
}

text = "hi this is as test ca"
translated = custom_make_translation(text, translation)

will give a value of translated "jk tjks is bc test sa"

But this one will prioritize "c" over "ca" as it is earlier in the dict

translation = {
    "hi":"jk", 
    "as":"bc",
    "c": "i have priority",
    "ca":"sa"
}

text = "hi this is as test ca"
translated = custom_make_translation(text, translation)

will give a value of translated "jk tjks is bc test i have prioritya"

So make sure you use it with caution.

Also, using regex rather then .replace in a for loop assures you make all the replacements at once. Otherwise if you have text "a" and translation map: {"a": "ab", "ab": "abc"} the translation will end up being "abc" rather than "ab"

Upvotes: 7

Related Questions