55

Is there a way to do character translation / transliteration (kind of like the tr command) using Python?

Some examples in Perl would be:

my $string = "some fields";
$string =~ tr/dies/eaid/;
print $string;  # domi failed

$string = 'the cat sat on the mat.';
$string =~ tr/a-z/b/d;
print "$string\n";  # b b   b.  (because option "d" is used to delete characters not replaced)
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
hhafez
  • 38,949
  • 39
  • 113
  • 143
  • 1
    For a Perl guy, calling it translation — as opposed to transliteration — made finding the right thing to do a bit more complicated. – Trenton Oct 16 '18 at 17:36
  • For me, the simplest is a [dictionary replace](https://stackoverflow.com/questions/2400504/easiest-way-to-replace-a-string-using-a-dictionary-of-replacements). – Ethan Bradford May 20 '19 at 20:52
  • I've done this [using a dictionary](https://stackoverflow.com/questions/2400504/easiest-way-to-replace-a-string-using-a-dictionary-of-replacements). – Ethan Bradford May 20 '19 at 20:54

6 Answers6

54

See string.translate

import string
"abc".translate(string.maketrans("abc", "def")) # => "def"

Note the doc's comments about subtleties in the translation of unicode strings.

And for Python 3, you can use directly:

str.translate(str.maketrans("abc", "def"))

Edit: Since tr is a bit more advanced, also consider using re.sub.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Richard Levasseur
  • 14,562
  • 6
  • 50
  • 63
28

If you're using python3 translate is less verbose:

>>> 'abc'.translate(str.maketrans('ac','xy'))
'xby'

Ahh.. and there is also equivalent to tr -d:

>>> "abc".translate(str.maketrans('','','b'))
'ac' 

For tr -d with python2.x use an additional argument to translate function:

>>> "abc".translate(None, 'b')
'ac'
Telemachus
  • 19,459
  • 7
  • 57
  • 79
Piotr Czapla
  • 25,734
  • 24
  • 99
  • 122
6

I has developed python-tr, implemented tr algorithm. Let's try it.

Install:

$ pip install python-tr

Example:

>>> from tr import tr
>>> tr('bn', 'cr', 'bunny')
'curry'
>>> tr('n', '', 'bunny', 'd')
'buy'
>>> tr('n', 'u', 'bunny', 'c')
'uunnu'
>>> tr('n', '', 'bunny', 's')
'buny'
>>> tr('bn', '', 'bunny', 'cd')
'bnn'
>>> tr('bn', 'cr', 'bunny', 'cs')
'brnnr'
>>> tr('bn', 'cr', 'bunny', 'ds')
'uy'
Yukino Ikegami
  • 129
  • 1
  • 5
3

In Python 2, unicode.translate() accepts ordinary mappings, ie. there's no need to import anything either:

>>> u'abc+-'.translate({ord('+'): u'-', ord('-'): u'+', ord('b'): None})
u'ac-+'

The translate() method is especially useful for swapping characters (as '+' and '-' above), which can't be done with replace(), and using re.sub() isn't very straightforward for that purpose either.

I have to admit, however, that the repeated use of ord() doesn't make the code look like nice and tidy.

lenz
  • 5,658
  • 5
  • 24
  • 44
1

We build a map and then translate letter by letter. When using get for dictionary then the second argument specifying what to return if not find anything.

It could be easily transferred to separate function. Mostly should be very efficient.

def transy(strin, old, new):
  assert len(old)==len(new)
  trans = dict(zip(list(old),list(new)))
  res =  "".join([trans.get(i,i) for i in strin])
  return res

>>> transy("abcd", "abc", "xyz")
'xyzd'
polkas
  • 3,797
  • 1
  • 12
  • 25
-5

A simpler approach may be to use replace. e.g.

 "abc".replace("abc", "def")
'def'

No need to import anything. Works in Python 2.x