6

When and why to use the former instead of the latter and vice versa?

It is not entirely clear why some use the former and why some use the latter.

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
Outcast
  • 4,967
  • 5
  • 44
  • 99
  • 1
    Here's an exercise that may convince you of the value of `str.translate`: using only .replace calls, replace all instances of "A" in a string with "B" and vice versa. Note that `"ABBA".replace("A", "B").replace("B", "A")` does not evaluate to "BAAB" as desired. – Kevin May 30 '19 at 12:53
  • @Kevin, thanks but firstly your example is not clear at all (you better write a longer comment/answer) and secondly it is not that I am not convinced about str.translate but it is about understanding the differences of these two and when each one is better to be used. – Outcast May 30 '19 at 12:55
  • I will be more explicit: No combination of .replace calls can possibly do the same thing that `s.translate(str.maketrans({"A":"B", "B":"A"}))` does. Even clever placeholder strategies like `s.replace("A", "_").replace("B", "A").replace("_", "B")` will fail to produce the correct output if `s` contains the placeholder character to begin with. – Kevin May 30 '19 at 12:58
  • @Kevin if you want you can give me a specific answer here: https://stackoverflow.com/questions/56378872/replace-multiple-special-characters-str-translate-vs-str-replace. – Outcast May 30 '19 at 13:02
  • Also @Kevin cool but I am still interesting to know the difference in the computational complexity of these two methods (for the same task at each time apparently). – Outcast May 30 '19 at 13:07

1 Answers1

7

They serve different purposes.

translate can only replace single characters with arbitrary strings, but a single call can perform multiple replacements. Its argument is a special table that maps single characters to arbitrary strings.

replace can only replace a single string, but that string can have arbitrary length.

>>> table = str.maketrans({'f': 'b', 'o': 'r'})
>>> table
{102: 'b', 111: 'r'}
>>> 'foo'.translate(table)
'brr'
>>> 'foo'.translate(str.maketrans({'fo': 'ff'}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: string keys in translate table must be of length 1
>>> 'foo'.replace('fo', 'ff')
'ffo'
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you for your answer (upvote). To start with, I assume that you talk about Python 3 (right?). Moreover, so in the case of multiple single characters is `translate` much more efficient than a loop with `replace`? – Outcast May 30 '19 at 12:52
  • I wouldn't say it's a matter of efficiency -- rather, a loop with multiple replace calls may produce the incorrect result. My comment on the question hints at this. – Kevin May 30 '19 at 12:54
  • Also, in Python 2, you used `string.maketrans` to make the table, which *had* to a string of length 256, which specified the replacement character for each of the 256 8-bit characters. Python 3's `str.maketrans` is more flexible, allowing replacements of arbitrary Unicode code points. – chepner May 30 '19 at 13:14
  • So there are at least two questions: 1) How these two methods compare in cases where both can be applied (e.g. single characters substistution)?, 2) Are you sure that with translate() you cannot map 2-chars, 3-chars and you can only work single characters? I had the impression that you could do the former too. – Outcast May 30 '19 at 13:32
  • `translate` operates on a character-by-character basis; `maketrans` won't create a mapping that that has multicharacter keys; if fact, the table it returns has integer keys, corresponding to the return value of `ord`. `translate` itself appears to simply ignore keys that aren't integers. – chepner May 30 '19 at 13:35
  • Ok (your answer apparently is a answer to my second question) – Outcast May 30 '19 at 13:53
  • By the way, char-by-char but still this means I think that you pass a 2-char to translate to another 2-char (but char-by-char). So my point is that at least the example that you gave above with .replace you you also do this with translate() I think. – Outcast May 30 '19 at 13:55