Here's a simple solution that makes use of the %
modulo operator to shift letters backwards.
It basically collects all of the letters in a reverse index lookup dictionary, so looking up letter positions is O(1)
instead of using list.index()
, which is linear O(N)
lookups.
Then it goes through each letter and calculates the shift value from the letter index e.g. for the letter a
with a shift value of 7
, the calculation will be (0 - 7) % 26
, which will give 19
, the position of u
.
Then once you have this shift value, convert it to uppercase or lowercase depending on the case of the original letter.
At the end we just str.join()
the result list into one string. This is more efficient than doing +=
to join strings.
Demo:
from string import ascii_lowercase
def letter_backwards_shift(word, shift):
letter_lookups = {letter: idx for idx, letter in enumerate(ascii_lowercase)}
alphabet = list(letter_lookups)
result = []
for letter in word:
idx = letter_lookups[letter.lower()]
shifted_letter = alphabet[(idx - shift) % len(alphabet)]
if letter.isupper():
result.append(shifted_letter.upper())
else:
result.append(shifted_letter.lower())
return ''.join(result)
Output:
>>> letter_backwards_shift('baNaNa', 7)
utGtGt
I would probably go with @Patrick Artner's pythonic solution. I just showed the above implementation as a learning exercise :-).