Reputation: 1674
I have a for
loop:
def decode(encoded):
r = []
a_l = string.ascii_letters
r_l = a_l[::-1]
for c in list(encoded):
if c in r_l:
i = a_l.index(c)
c = r_l[i]
r.append(c)
return "".join(r)
I want to compress the entire function to one-liner. So far, I've come up with:
r = [r_l[a_l.index(c)] for c in encoded if c in r_l]
This, however, skips over the punctuation characters. How can I do this?
If you need a test string, it's an atbash cipher:
def atbash(payload):
all_letters = string.ascii_letters
all_letters_reversed = all_letters[::-1]
retval = []
for c in list(payload):
if c in all_letters:
index = all_letters.index(c)
c = all_letters_reversed[index]
retval.append(c)
return ''.join(retval)
Upvotes: 0
Views: 47
Reputation: 9019
As @Prune pointed out, you are missing the ternary portion of your list comprehension. Here is a much shorter implementation of your code using list comprehensions:
import string
def atbash(payload):
return ''.join([r_l[a_l.index(c)] for c in list(payload) if c in a_l])
def decode(encoded):
return ''.join([r_l[a_l.index(c)] if c in r_l else c for c in list(encoded)])
test = 'test'
a_l = string.ascii_letters
r_l = a_l[::-1]
x = atbash(test)
decode(x)
Upvotes: 0
Reputation: 77837
You're missing the ternary part of the operation to add any "other" characters:
... if c in r_l ... else c ...
Now, you'll need to insert that else c
into just the right place to be the alternative to your translated character. I leave that as an exercise for the student. I trust that hint unblocks your brain paths.
Upvotes: 2