0

For example, I have a lst = "ABCXYZ", and I expect the output to be "CDEZAB"

The best method I've come up with so far is:

"".join(chr((ord(x)-ord('A')+2)%26+ord('A')) for x in lst)

Which is awkward. Using a dictionary like {'A': 'C', 'B': 'D', ……, 'X': 'Z', 'Y': 'A', 'Z': 'B'} seems more Pythonic, but is even more awkward.

Any ideas?

nalzok
  • 14,965
  • 21
  • 72
  • 139
  • 1
    The dictionary can be created very easily though: `conv = dict(zip(alphabet, alphabet[2:] + alphabet[:2]))` Then converting is as easy as `''.join(map(conv.get, string))` – BlackBear Apr 14 '17 at 12:59
  • Possible duplicate of [Caesar Cipher Function in Python](http://stackoverflow.com/questions/8886947/caesar-cipher-function-in-python) – Paul Hankin Apr 14 '17 at 13:08

2 Answers2

6

You can simply build that dictionary:

>>> import string
>>> dict(zip(string.uppercase, string.uppercase[2:]+string.uppercase[:2]))
{'A': 'C', 'C': 'E', 'B': 'D', 'E': 'G', 'D': 'F', 'G': 'I', 'F': 'H', 'I': 'K', 'H': 'J', 'K': 'M', 'J': 'L', 'M': 'O', 'L': 'N', 'O': 'Q', 'N': 'P', 'Q': 'S', 'P': 'R', 'S': 'U', 'R': 'T', 'U': 'W', 'T': 'V', 'W': 'Y', 'V': 'X', 'Y': 'A', 'X': 'Z', 'Z': 'B'}

And then use it:

>>> m = dict(zip(string.uppercase, string.uppercase[2:]+string.uppercase[:2]))
>>> ''.join(map(m.get, "ABCXYZ"))
'CDEZAB'
Dan D.
  • 73,243
  • 15
  • 104
  • 123
2

What you suggest makes sense to me; it can be a little more elegant with a few built-ins.

import string

s = "ABCXYZ"

d = dict(enumerate(string.ascii_uppercase))
''.join([d[(string.ascii_uppercase.index(c) + 2)%26] for c in s])
cohoz
  • 750
  • 4
  • 16