您的位置:首页 > 编程语言 > Python开发

python 内置函数map/filter/reduce

2014-02-14 17:02 323 查看
Built-in functions
==================

Let's look in more detail at built-in functions often used with iterators.

Two of Python's built-in functions, :func:`map` and :func:`filter`, are somewhat
obsolete; they duplicate the features of list comprehensions but return actual
lists instead of iterators.

``map(f, iterA, iterB, ...)`` returns a list containing ``f(iterA[0], iterB[0]),
f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ...``.

>>> def upper(s):
...     return s.upper()

>>> map(upper, ['sentence', 'fragment'])
['SENTENCE', 'FRAGMENT']

>>> [upper(s) for s in ['sentence', 'fragment']]
['SENTENCE', 'FRAGMENT']

As shown above, you can achieve the same effect with a list comprehension.  The
:func:`itertools.imap` function does the same thing but can handle infinite
iterators; it'll be discussed later, in the section on the :mod:`itertools` module.

``filter(predicate, iter)`` returns a list that contains all the sequence
elements that meet a certain condition, and is similarly duplicated by list
comprehensions.  A **predicate** is a function that returns the truth value of
some condition; for use with :func:`filter`, the predicate must take a single
value.

>>> def is_even(x):
...     return (x % 2) == 0

>>> filter(is_even, range(10))
[0, 2, 4, 6, 8]

This can also be written as a list comprehension:

>>> [x for x in range(10) if is_even(x)]
[0, 2, 4, 6, 8]

:func:`filter` also has a counterpart in the :mod:`itertools` module,
:func:`itertools.ifilter`, that returns an iterator and can therefore handle
infinite sequences just as :func:`itertools.imap` can.

``reduce(func, iter, [initial_value])`` doesn't have a counterpart in the
:mod:`itertools` module because it cumulatively performs an operation on all the
iterable's elements and therefore can't be applied to infinite iterables.
``func`` must be a function that takes two elements and returns a single value.
:func:`reduce` takes the first two elements A and B returned by the iterator and
calculates ``func(A, B)``.  It then requests the third element, C, calculates
``func(func(A, B), C)``, combines this result with the fourth element returned,
and continues until the iterable is exhausted.  If the iterable returns no
values at all, a :exc:`TypeError` exception is raised.  If the initial value is
supplied, it's used as a starting point and ``func(initial_value, A)`` is the
first calculation.

>>> import operator
>>> reduce(operator.concat, ['A', 'BB', 'C'])
'ABBC'
>>> reduce(operator.concat, [])
Traceback (most recent call last):
...
TypeError: reduce() of empty sequence with no initial value
>>> reduce(operator.mul, [1,2,3], 1)
6
>>> reduce(operator.mul, [], 1)
1

If you use :func:`operator.add` with :func:`reduce`, you'll add up all the
elements of the iterable.  This case is so common that there's a special
built-in called :func:`sum` to compute it:

>>> reduce(operator.add, [1,2,3,4], 0)
10
>>> sum([1,2,3,4])
10
>>> sum([])
0

For many uses of :func:`reduce`, though, it can be clearer to just write the
obvious :keyword:`for` loop::

# Instead of:
product = reduce(operator.mul, [1,2,3], 1)

# You can write:
product = 1
for i in [1,2,3]:
product *= i
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: