13aal
13aal

Reputation: 1674

Turning a for loop into a list comprehension

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

Answers (2)

rahlf23
rahlf23

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

Prune
Prune

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

Related Questions