4

When should you use map/filter instead of a list comprehension or generator expression?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
hekevintran
  • 22,822
  • 32
  • 111
  • 180

2 Answers2

8

You might want to take a look at the responses to this question:

Python List Comprehension Vs. Map

Also, here's a relevant essay from Guido, creator and BDFL of Python:

http://www.artima.com/weblogs/viewpost.jsp?thread=98196

Personally, I prefer list comprehensions and generator expressions because their meaning is more obvious when reading the code.

Community
  • 1
  • 1
ʇsәɹoɈ
  • 22,757
  • 7
  • 55
  • 61
1

List comprehensions and generator expressions are generally considered more pythonic. When writing python code it is best to use list comprehensions and generator expressions simply because it's the way python programmers tend to do things.

Map and filter both return list objects just like list comprehensions. Generator expressions return a generator. With a generator, computation happens as needed instead of computing and storing the results. This can lead to lower memory usage if the input sizes are large. Also, keep in mind that generators are not indexable. They must be read from sequentially.

Below are some examples of how memory usage would differ when using different methods transforming a sequence of numbers and summing them using list comprehension, generator expressions and map.

k=1000

def transform(input):
    return input + 1

"""
  1. range(k) allocates a k element list [0...k]
  2. Iterate over each element in that list and compute the transform
  3. Store the results in a list
  4. Pass the list to sum

Memory: Allocates enough 2 lists of size k
"""
print sum([transform(i) for i in range(k)])

"""
  1. Create an xrange object
  2. Pass transform and xrange object to map
  3. Map returns a list of results [1...k+1]
  4. Pass list to sum

Memory: Creates a constant size object and creates a list of size k
"""
print sum(map(transform, xrange(k)))

"""
  1. Create an xrange object
  2. Create a generator object
  3. Pass generator object to sum

Memory: Allocates 2 objects of constant size
"""
print sum(transform(i) for i in xrange(k))

"""
Create a generator object and operate on it directly
"""
g = (transform(i) for i in xrange(k))
print dir(g)
print g.next()
print g.next()
print g.next()
Evan
  • 6,151
  • 1
  • 26
  • 43
  • *"Map and filter come from more functional languages."* As do list comprehensions (which were inspired by the feature in Haskell) and generator expressions (which descend from list comprehensions and--really--are more like the sorts of operations you would perform in a non-strict functional language.) – Mike Graham Jun 05 '10 at 06:41
  • I know what the definitions are. I want to know the reasons why you would want to use map over a list comprehension. – hekevintran Jun 05 '10 at 07:06
  • Bad phrasing on my part so I cut it. In my experience map/filter are used more in functional (albeit strict functional) languages more than list comprehension just because the list comprehension would be syntactic sugar on top of map/filter and I know many languages try to limit the number of ways to skin cats. – Evan Jun 05 '10 at 07:21
  • 1
    Use what you wish. When I write python I always use list comprehension over map. – Evan Jun 05 '10 at 07:26