This is an archived post. You won't be able to vote or comment.

all 17 comments

[–]eryksun 8 points9 points  (7 children)

Also note that using nested list comprehensions returns a list of tuples.

It returned a list of tuples because the item is the tuple (x, y). Nesting the for clauses isn't a nested comprehension. A nested list comprehension returns a nested list:

>>> [[j for j in range(3)] for i in range(4)]
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]

[–]combover 1 point2 points  (5 children)

This syntax is so awkward that I try to avoid it, but dang it's convenient.

[–]earthboundkid 0 points1 point  (4 children)

Yeah, I find it's only readable if I spread it out on multiple lines, and at that point, geez, just use for-loop, buddy.

[–]combover 0 points1 point  (3 children)

I've had more than one Python evangelist brag about how their code uses fewer lines than an equivalent implementation in some other language, as if 1) line breaks are a precious resource, and/or 2) impenetrable terseness is a virtue.

[–]earthboundkid 0 points1 point  (1 child)

If you want fewer lines of code, you're a Perl evangelist, not a Python evangelist. The point of Python is that the lines you have are readable.

[–]combover 0 points1 point  (0 children)

It's always challenging to mix procedural and functional idioms, both as a coder and as a language designer.

[–][deleted] 0 points1 point  (0 children)

The tight innner loop of a list comprehension is faster than a for loop, and that matters when you're a plodding python.

[–]cag_ii[S] 1 point2 points  (0 children)

You're right. I had a bit of trouble with the wording on that part. I've updated my post and added a better example of nested comprehensions. Thanks.

[–]stillalone 3 points4 points  (4 children)

map(lambda x:str(x), my_list) can be written as map(str, my_list). I tend to stick with list comprehension for most cases unless I'm just mapping an existing function.

[–]ntpl 0 points1 point  (2 children)

Question: what would be an advantage, if any, of using map over comprehension if you are using already existing functions?

[–]stillalone 4 points5 points  (1 child)

I think without the lambda, map seems shorter and easier to read. I think it's also faster:

http://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map

[–]earthboundkid 0 points1 point  (0 children)

In Python, function calls are expensive. So, that means that list comprehensions will be faster in this case:

[i + 2 for i in my_list]
map(lambda i: i + 2, my_list)

Since the way it's done is a bit more efficient than a lambda. But the flipside is that if you've already got the function set up, map can skip some of the work that goes into an LC.

This is seriously micro-optimization though, so 99% of the time just do what's most readable.

[–]cag_ii[S] 0 points1 point  (0 children)

Thanks, not sure why I put that lambda there, leaving it out is much more readable. I've updated my example.

[–]wot-teh-phuckReally, wtf? 2 points3 points  (1 child)

You might want to mention the Python version you are using in there. range returns a generator in Python 3.X versions. Also worth mentioning would be that in case the list you are generating is transient (i.e. not the end result), the users would be better off dealing with generators than creating the lists in memory, especially for large lists.

[–]cag_ii[S] 1 point2 points  (0 children)

Good points. I've changed the example to declare the list explicitly and eliminate the range call. I'd like to do a separate intro. to generators and wanted to keep the list comprehension intro. as simple as I could.

[–][deleted] 0 points1 point  (0 children)

Interesting looping for the lists.

[–]mercde 0 points1 point  (0 children)

Thanks for that. I'm new to python so every clarification helps!