Cheeso
Cheeso

Reputation: 192617

Why does the Python Tutorial say that list comprehensions are more flexible than map()?

In the Python Tutorial, it says:

enter image description here

Why? I don't see how comprehensions are "more flexible". It seems to me to be only a difference in syntax. I can easily do:

def my_round(i):
    return str(round(355/113.0, i))

a = map(my_round, range(1, 6))

I don't see how map() lacks flexibility here.

Can anyone elaborate?

Upvotes: 3

Views: 250

Answers (7)

Mu Mind
Mu Mind

Reputation: 11214

As others have said, the difference is subtle but there are cases where list comprehensions have a noticeable advantage in power and readability. I don't think that example from the tutorial was tailor-made to show off the advantages of list comprehensions, but just try writing something like this sucker with map/filter:

[i for (i,c) in enumerate('abcdefghijklmnopqrstuvwxyz') if c in 'aeiou']

Here's the best I can come up with:

map(lambda (i, c): i, filter(lambda (i,c): c in 'aeiou',
    enumerate('abcdefghijklmnopqrstuvwxyz')))

Upvotes: 0

robert
robert

Reputation: 34438

As S.Lott implied, list comprehension can do more than map. You need both itertools.imap and itertools.ifilter to cover what can be done with a comprehension.

[ str(round(355/113.0, i)) for i in range(1,12) if prime(i) ]

is the same as

import itertools
list(
   itertools.imap(
      lambda x: str(round(355/113.0, x)), 
      itertools.ifilter(
         prime,
         range(1,12))))

Upvotes: 0

intuited
intuited

Reputation: 24084

In the case of your example, it is not map which is providing the flexibility, it is the function definition construct. You could also use that function in a list comprehension, but would not need to.

Upvotes: 0

user395760
user395760

Reputation:

The difference is relatively small, but you have to write a fully-fledged def including name or a lambda to use nontrivial expressions with map, while you can just go and use them in a list comprehension. Also, list comprehensions include filtering while you'd need a seperate filter call for that (inefficient and the parens quickly grow beyond what can be managed easily).

Upvotes: 6

Jochen Ritzel
Jochen Ritzel

Reputation: 107696

map requires you to define my_round while the LC does not.

Nobody said the difference was huge ;-)

Upvotes: 1

Gabe
Gabe

Reputation: 86788

List comprehensions can contain nested loops and conditionals:

nonzeros = [val for y in rows
                for val in y.cols
                if val != 0]

Upvotes: 6

S.Lott
S.Lott

Reputation: 391992

[ str(round(355/113.0, i)) for i in range(1,12) if prime(i) ]

Upvotes: 1

Related Questions