reduce() anomaly?

Peter Otten __peter__ at web.de
Wed Nov 5 13:40:38 EST 2003


Stephen C. Waterbury wrote:

> This seems like it ought to work, according to the
> description of reduce(), but it doesn't.  Is this
> a bug, or am I missing something?
> 
> Python 2.3.2 (#1, Oct 20 2003, 01:04:35)
> [GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> d1 = {'a':1}
>  >>> d2 = {'b':2}
>  >>> d3 = {'c':3}
>  >>> l = [d1, d2, d3]
>  >>> d4 = reduce(lambda x, y: x.update(y), l)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in ?
>    File "<stdin>", line 1, in <lambda>
> AttributeError: 'NoneType' object has no attribute 'update'
>  >>> d4 = reduce(lambda x, y: x.update(y), l, {})
> Traceback (most recent call last):
>    File "<stdin>", line 1, in ?
>    File "<stdin>", line 1, in <lambda>
> AttributeError: 'NoneType' object has no attribute 'update'
> 
> - Steve.

No bug, your lambda evaluates d1.update(d2) on the first call and then
returns the result of the update() method which is None. So on the secend
call None.update(d3) fails. Here's what you might have intended:

>>> d1 = {'a':1}
>>> d2 = {'b':2}
>>> d3 = {'c':3}
>>> l = [d1, d2, d3]
>>> d4 = reduce(lambda x, y: x.update(y) or x, l)
>>> d4
{'a': 1, 'c': 3, 'b': 2}

Note the side effect on d1

>>> d1
{'a': 1, 'c': 3, 'b': 2}

if you don't provide an initial dictionary.

Peter





More information about the Python-list mailing list