3

I'm Python beginner can't get my head around. How do I change for example a = [[1,2],[3,4],[5,6]] into "12\n34\n56" string format.

This is as far as i got but it goes into newline with each number.

def change(a):
    c = ""
    for r in a:
        for b in r:
            c += str(b) + "\n"
    return c
0

2 Answers 2

12

but it goes into newline with each number

That’s because you add the newline after each number instead of after each sublist r. If you want that instead, you should append the newline there:

c = ''
for r in a:
    for b in r:
        c += str(b)
    c += '\n'
return c

But note that appending to a string is very inefficient, as it ends up creating lots of intermediary strings. Usually, you would create a list instead to which you append your string parts, and then finally join that list to convert it to a single string:

c = []
for r in a:
    for b in r:
        c.append(str(b))
    c.append('\n')
return ''.join(c)

And then, you can also use list expressions to make this shorter in multiple steps; first for the inner list:

c = []
for r in a:
    c.extend([str(b) for b in r])
    c.append('\n')
return ''.join(c)

And you can join that list comprehension first:

c = []
for r in a:
    c.append(''.join([str(b) for b in r]))
    c.append('\n')
return ''.join(c)

Then you can move the newline into the outer join, and make a new list comprehension for the outer list:

c = [''.join([str(b) for b in r]) for r in a]
return '\n'.join(c)

And at that point, you can make it a one-liner too:

return '\n'.join([''.join([str(b) for b in r]) for r in a])

As Padraic pointed out in the comments, joining on the newline character will also prevent the string from having a trailing \n which you would end up if you kept adding it in the loop. Otherwise, you could have used str.rstrip('\n') to get rid of it afterwards.

Sign up to request clarification or add additional context in comments.

5 Comments

Tnx so much nice explanation! :)
I'd go with the slightly more verbose version that uses list comprehensions: '\n'.join([''.join([str(v) for v in u]) for u in a]). The generator version looks neater, but the list comp has less overhead. And there's no advantage to passing a gen exp to join since it needs all the substrings before it starts work (otherwise there'd be no advantage in using join() over simple string concatenation).
Your code actually gives the wrong result, I had an answer I deleted as you had answered first but you need to remove the last newline or keep a check on where you are and not add a newline if you are at the last grouping
@PadraicCunningham: +1. Or just use the join-based approach, so you don't get the unwanted trailing \n. Alternatively, just use slicing to remove the trailing \n from the string... but that's a bit messy.
@PM2Ring, yep join is certainly the solution to use, I just meant if you were to actually use a loop then that is something you have to catch.
7

Using str.join with generator expression:

>>> a = [[1,2], [3,4], [5,6]]
>>> '\n'.join(''.join(map(str, xs)) for xs in a)
'12\n34\n56'

3 Comments

Just curious, why do you map(str, xs) instead of just str(xs)? Isn't the latter cheaper?
@Lawrence, str(xs) results in '[1, 2]', while ''.join(map(str, [1, 2])) gives you 12.
Right, I missed the fact that xs is in fact a list :)

Your Answer

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.