user2770379
user2770379

Reputation:

Printing list only outputs one result

I have this code that I used for a python challenge, now it use to work perfectly, but now the only result I get as an output is 'i'.

I'm not sure but I'm assuming that my code isn't storing all the values I'm giving ascii_list for some reason.

a = """g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.""" 
def ascii_list(a):
    for i in a: return chr(ord(i)+2)

alist = ascii_list(a)

print ("".join(alist))

Now my question is, why is it doing this and where have I gone wrong? I'm using Python 3.3.

(Go easy on me I've tried to do this right)

Upvotes: 0

Views: 98

Answers (4)

abarnert
abarnert

Reputation: 365717

The problem is here:

def ascii_list(a):
    for i in a: return chr(ord(i)+2)

The first time through the loop, you return. That ends the function, and the loop, on the first value.

You could change this into a generator function:

def ascii_list(a):
    for i in a: yield chr(ord(i)+2)

Intuitively, this is pretty simple. You can yield as many times as you want, instead of returning one value. When someone tries to loop over the result of your function, or pass it to a function like list or join, it will get all the yielded results.

But if this is too confusing, and you're not ready to learn about generators yet, you could also build up a list explicitly:

def ascii_list(a):
    return [chr(ord(i)+2) for i in a]

… or:

def ascii_list(a):
    result = []
    for i in a: result.append(chr(ord(i)+2))
    return result

As Jon Clements pointed out in a comment, this isn't quite the right algorithm for what you're trying to do. First, you need to "roll over" past the end of the alphabet—otherwise, you get { instead of a and | instead of b. If you understand the % (modulus/remainder) operator, you can do this in a single step; if not, you can use an if/else. Second, you don't want to translate non-letters like space or . at all; for this, you probably want and if/else. Writing this out verbosely:

def ascii_list(a):
    for i in a:
        if not i.isalpha():
            rot = 0
        else if i.lower() > 'x':
            rot = 2 - 26
        else:
            rot = 2
        yield chr(ord(i) + rot)

Upvotes: 3

Burhan Khalid
Burhan Khalid

Reputation: 174624

In addition to a list comprehension, you can also use a map with your method:

def get_code(i):
    return chr(ord(i)+2)

''.join(map(get_code, a))

Or a more compact version, with a lambda:

''.join(map(lambda i: chr(ord(i)+2), a))

Upvotes: 0

Tom Dalton
Tom Dalton

Reputation: 6190

You start iterating the string, get to character 'g', then return chr(ord('g') + 2). That returns 'i' and terminates the loop.

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308206

That's because you're returning in the first pass of the loop. You really want a list comprehension:

return [chr(ord(i)+2) for i in a]

Upvotes: 1

Related Questions