20

I'm a Python newbie.

How come this doesn't work in Python 3.1?

from string import maketrans   # Required to call maketrans function.

intab = "aeiou"
outtab = "12345"
trantab = maketrans(intab, outtab)

str = "this is string example....wow!!!";
print str.translate(trantab);

When I executed the above code, I get the following instead:

Traceback (most recent call last):
  File "<pyshell#119>", line 1, in <module>
    transtab = maketrans(intab, outtab)
  File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/string.py", line 60, in maketrans
    raise TypeError("maketrans arguments must be bytes objects")
TypeError: maketrans arguments must be bytes objects

What does "must be bytes objects" mean? Could anyone please help post a working code for Python 3.1 if it's possible?

agf
  • 171,228
  • 44
  • 289
  • 238
sivabudh
  • 31,807
  • 63
  • 162
  • 228
  • It doesn't work, because string.maketrans doesn't do what you think. Which is why it was deprecated in 3.1 for bytes.maketrans. You should use str.maketrans instead of string.maketrans for strings, and bytes.maketrans for bytes. – Lennart Regebro Apr 26 '12 at 10:03
  • To see the difference yourself, compare the output of `print(str.maketrans("aeiou","12345"))` --which is `{97: 49, 101: 50, 105: 51, 111: 52, 117: 53}` --to the output of `print(bytes.maketrans(b"aeiou",b"12345"))` (which is tool long and ugly to show here.) – MarkHu Jun 08 '17 at 23:26

9 Answers9

36

You don't need to use bytes.maketrans() when str would be simpler and eliminate the need for the 'b' prefix:

print("Swap vowels for numbers.".translate(str.maketrans('aeiou', '12345')))
tshepang
  • 12,111
  • 21
  • 91
  • 136
theNewt
  • 369
  • 1
  • 3
  • 2
16

Stop trying to learn Python 3 by reading Python 2 documentation.

intab = 'aeiou'
outtab = '12345'

s = 'this is string example....wow!!!'

print(s.translate({ord(x): y for (x, y) in zip(intab, outtab)}))
MERose
  • 4,048
  • 7
  • 53
  • 79
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 7
    Pardon me, but as a newbie, I have no clue which is P2 doc, and which is P3. Thanks for the code though. – sivabudh Jun 13 '10 at 04:41
  • 7
    Use the official docs.python.org: the version is written at the top of each page. HTH – merwok Apr 02 '12 at 10:56
  • 1
    Why am I getting this error when I try to run this? `print(s.translate({ord(x): y for (x, y) in zip(intab, outtab)})) TypeError: expected a character buffer object` – Insarov May 02 '14 at 17:46
  • 18
    downvoted for a pissy attitude. So you have 423k points. Answer questions with the same grace as Guido - _that's_ pythonic. – user192127 Jun 03 '16 at 22:42
11

Strings are not bytes.

This is a simple definition in Python 3.

Strings are Unicode (which are not bytes) Unicode strings use "..." or '...'

Bytes are bytes (which are not strings) Byte strings use b"..." or b'...'.

Use b"aeiou" to create a byte sequence composed of the ASCII codes for certain letters.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
8

In Python 3, the string.maketrans() function is deprecated and is replaced by new static methods, bytes.maketrans() and bytearray.maketrans().

This change solves the confusion around which types were supported by the string module.

Now str, bytes, and bytearray each have their own maketrans and translate methods with intermediate translation tables of the appropriate type.

bignose
  • 30,281
  • 14
  • 77
  • 110
Manoj Hirway
  • 131
  • 1
  • 7
5
"this is string example....wow!!!".translate(str.maketrans("aeiou","12345"))

This works, and no additional byte transformation. I don't know the reason why to use byte instead of str.

Peorth
  • 79
  • 1
  • 4
1

If you absolutely insist on working with 8-bit bytes:

>>> intab = b"aeiou"
>>> outtab = b"12345"
>>> trantab = bytes.maketrans(intab, outtab)
>>> strg = b"this is string example....wow!!!";
>>> print(strg.translate(trantab));
b'th3s 3s str3ng 2x1mpl2....w4w!!!'
>>>
John Machin
  • 81,303
  • 11
  • 141
  • 189
  • 1
    I don't insist on working with 8-bit bytes, but it's hard to find a computer that supports 6-bit or 4-bit bytes anymore. – LarsH Jun 05 '19 at 01:13
0

Hey here is the simple one liner which worked perfectly for me

import string
a = "Learning Tranlate() Methods"
print (a.translate(bytes.maketrans(b"aeiou", b"12345")))*
OUTPUT :::: L21rn3ng Tr1nl1t2() M2th4ds
0

Here is an example of performing translation and deletion, in Python 2 or 3:

import sys


DELETE_CHARS = '!@#$%^*()+=?\'\"{}[]<>!`:;|\\/-,.'


if sys.version_info < (3,):

    import string

    def fix_string(s, old=None, new=None):
        if old:
            table = string.maketrans(old, new)
        else:
            table = None
        return s.translate(table, DELETE_CHARS)

else:

    def fix_string(s, old='', new=''):
        table = s.maketrans(old, new, DELETE_CHARS)
        return s.translate(table)
pourhaus
  • 566
  • 6
  • 9
0

maketrans is a string function

use below logic to use translate using maketrans

print('maketrans' , '& translate')
intab = "aeiou"
outtab = "12345"
str = "Fruits are delicious and healthy!!!"
trantab = str.maketrans(intab, outtab)
print (str.translate(trantab))