Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Python list comprehensions the same thing as map/grep in Perl?

Tags:

python

list

perl

I was having some trouble grokking the list comprehension syntax in Python, so I started thinking about how to achieve the same thing in Perl, which I'm more familiar with. I realized that the basic examples (taken from this page) can all be done in Perl with map or grep.

E.g.

(python)                            (perl)                  
S = [x**2 for x in range(10)]       @S = map { $_**2 } ( 0..9 );
V = [2**i for i in range(13)]       @V = map { 2**$_ } ( 0..12 );
M = [x for x in S if x % 2 == 0]    @M = grep { $_ % 2 == 0 } @S;

So is "list comprehension" just a fancy term for "map and/or filter a list" or is there more to it?

like image 397
friedo Avatar asked Sep 13 '09 21:09

friedo


People also ask

Are list comprehensions Python?

List comprehensions are often described as being more Pythonic than loops or map() . But rather than blindly accepting that assessment, it's worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives.

What is the difference between map and list in python?

List comprehension is more concise and easier to read as compared to map. List comprehension are used when a list of results is required as map only returns a map object and does not return any list. Map is faster in case of calling an already defined function (as no lambda is required).

Are list comprehensions faster than map?

Map function is faster than list comprehension when the formula is already defined as a function earlier. So, that map function is used without lambda expression.

Does list comprehension work on strings?

List comprehension works with string lists also. The following creates a new list of strings that contains 'a'.


2 Answers

You are correct: a list comprehension is essentially just syntactic sugar for map and filter (terms from the functional programming world).

Hopefully this sample code demonstrates their equality:

>>> # Python 2
>>> [x**2 for x in range(10)] == map(lambda x: x**2, range(10))
True
>>> [2**i for i in range(13)] == map(lambda x: 2**x, range(13))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == filter(lambda x: x % 2 == 0, S)
True

Note that this is only valid in Python 2.X, as SilentGhost pointed out in the comment. To make this compatible with Python 3, you'll have to wrap the calls to map or filter in the list constructor, because map and filter have been updated to return iterators, not lists.

>>> # Python 3
>>> [x**2 for x in range(10)] == list(map(lambda x: x**2, range(10)))
True
>>> [2**i for i in range(13)] == list(map(lambda x: 2**x, range(13)))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == list(filter(lambda x: x % 2 == 0, S))
True
like image 191
Mark Rushakoff Avatar answered Oct 07 '22 23:10

Mark Rushakoff


Yes, they are basically the same.

In fact Python also has a map function:

S = map(lambda x: x**2, range(10))

is the same as your first examples above. However, the list comprehension syntax is strongly preferred in Python. I believe Guido has been quoted as saying he regrets introducing the functional syntax at all.

However, where it gets really interesting is in the next evolution of list comprehensions, which is generators. These allow you to return an iterator - rather than processing the whole list at once, it does a single iteration and then returns, so that you don't have to hold the whole list in memory at the same time. Very powerful.

like image 31
Daniel Roseman Avatar answered Oct 07 '22 22:10

Daniel Roseman