3

I would like to replace every character of a string with the next one and the last should become first. Here is an example:

abcdefghijklmnopqrstuvwxyz

should become:

bcdefghijklmnopqrstuvwxyza

Is it possible to do it without using the replace function 26 times?

steady rain
  • 2,246
  • 3
  • 14
  • 18
BoumTAC
  • 3,531
  • 6
  • 32
  • 44

3 Answers3

10

You can use the str.translate() method to have Python replace characters by other characters in one step.

Use the string.maketrans() function to map ASCII characters to their targets; using string.ascii_lowercase can help here as it saves you typing all the letters yourself:

from string import ascii_lowercase
try:
    # Python 2
    from string import maketrans
except ImportError:
    # Python 3 made maketrans a static method
    maketrans = str.maketrans 

cipher_map = maketrans(ascii_lowercase, ascii_lowercase[1:] + ascii_lowercase[:1])
encrypted = text.translate(cipher_map)

Demo:

>>> from string import maketrans
>>> from string import ascii_lowercase
>>> cipher_map = maketrans(ascii_lowercase, ascii_lowercase[1:] + ascii_lowercase[:1])
>>> text = 'the quick brown fox jumped over the lazy dog'
>>> text.translate(cipher_map)
'uif rvjdl cspxo gpy kvnqfe pwfs uif mbaz eph'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
4

Sure, just use string slicing:

>>> s = "abcdefghijklmnopqrstuvwxyz"
>>> s[1:] + s[:1]
'bcdefghijklmnopqrstuvwxyza'

Basically, the operation you want to do is analogous to rotating the position of the characters by one place to the left. So, we can simply take the part of string after the first character, and add the first character to it.

EDIT: I assumed that OP is asking to rotate a string (which is plausible from his given input, the input string has 26 characters, and he might have been doing a manual replace for each character), in case the post is about creating a cipher, please check @Martjin's answer above.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • 1
    I didn't downvote, but judging by that downvote I guess OP wants a ROT-1 cipher rather than rotating a list/string. – Carsten Mar 27 '15 at 18:36
  • I think this is the better and more straightforward answer to the question as written. – Joe Mar 27 '15 at 18:46
0

Because string in Python is immutable you need convert string to list, replace, and then convert back to string. Here I use modulo.

def convert(text):
    lst = list(text)
    new_list = [text[i % len(text) +1] for i in lst]
    return "".join(new_list)

Don't use slicing because this is not efficient. Python will create new full copy string for every single changed char, because string is immutable.

Alexander R.
  • 1,756
  • 12
  • 19