0

I'm trying to replace the characters of the reversed alphabet with those of the alphabet. This is what I've got:

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
rev_alphabet = alphabet[::-1]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
def f(alph, rev_alph):
 return (alph, rev_alph)
char_list_of_tups = list(map(f, alphabet, rev_alphabet))
for alph, rev_alph in char_list_of_tups:
 sample = sample.replace(rev_alph, alph)
print(sample)

expected output: did you see last night's episode?

actual output: wrw you svv ozst nrtst's vprsowv?

I understand that I'm printing the last "replacement" of the whole iteration. How can I avoid this without appending it to a list and then running into problems with the spacing of the words?

asked Jun 17, 2022 at 13:55
3
  • 4
    Let's say your string is "ww" in 1st iteration the string would be "dd" in 2nd iteration "dd" would become "ww". Commented Jun 17, 2022 at 13:58
  • 2
    One option is to use str.maketrans and str.translate to do the translation in one pass and avoid the issue you are describing. Commented Jun 17, 2022 at 13:59
  • Side-note: list(map(f, alphabet, rev_alphabet)) is a slow (and verbose since you have to define f) way to spell list(zip(alphabet, rev_alphabet)). Commented Jun 17, 2022 at 14:06

3 Answers 3

5

Your problem here is that you lose data as you perform each replacement; for a simple example, consider an input of "az". On the first replacement pass, you replace 'z' with 'a', and now have "aa". When you get to replacing 'a' with 'z', it becomes "zz", because you can't tell the difference between an already replaced character and one that's still unchanged.

For single character replacements, you want to use the str.translate method (and the not strictly required, but useful helper function, str.maketrans), to do character by character transliteration across the string in a single pass.

from string import ascii_lowercase # No need to define the alphabet; Python provides it
 # You can use the original str form, no list needed
# Do this once up front, and reuse it for as many translate calls as you like
trans_map = str.maketrans(ascii_lowercase[::-1], ascii_lowercase)
sample = sample.translate(trans_map)
answered Jun 17, 2022 at 13:59
0
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# or
alphabet = [chr(97 + i) for i in range(0,26)]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
res = []
for ch in sample:
 if ch in alphabet:
 res.append(alphabet[-1 - alphabet.index(ch)])
 else:
 res.append(ch)
 
print("".join(res))
answered Jun 17, 2022 at 14:01
0

Another Way if you are ok with creating a new string instead.

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
dictRev = dict(zip(alphabet, alphabet[::-1]))
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
s1="".join([dictRev.get(char, char) for char in sample])
print(s1)

"did you see last night's episode?"

answered Jun 17, 2022 at 14:17
1
  • 1
    They must be okay with creating a new string; strings aren't mutable so any "mutation" makes a new one (their old code made 26 new strings). Your code could still reassign the result of the "".join back to sample and work just fine, the key is that you only performed one replacement per character, you didn't perform 26 such replacements). For all practical purposes, your code is a deoptimized version of str.translate (which is, internally, just a loop over the input doing the optimized C-level equivalent of what your "".join([dictRev.get(char, char) for char in sample]) is doing). Commented Jun 17, 2022 at 14:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.