When should you use map/filter instead of a list comprehension or generator expression?
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.
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()
精彩评论