Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reduce with empty set as initial value

Tags:

python

I have a list of list and I want to construct a set out of the elements present in all the sublists..

example : a = [[1,2],[2,3]] should give set([1,2,3])

I tried reduce(lambda x,y:x.update(y),a,set([])) but it raises AttributeError: 'NoneType' object has no attribute 'update'

Can someone tell me how to do this using reduce function ?

like image 295
Graddy Avatar asked Nov 30 '11 05:11

Graddy


2 Answers

As requested:

>>> a = [[1,2],[2,3]]
>>> reduce(lambda s, elems: s.union(elems), a, set())
set([1, 2, 3])

Another way just for fun:

>>> from itertools import chain
>>> set(chain.from_iterable(a))
set([1, 2, 3])

And one more just to be cool:

>>> set.union(set(), *a)
set([1, 2, 3])
like image 83
Raymond Hettinger Avatar answered Sep 21 '22 01:09

Raymond Hettinger


The problem is that update() on a set returns None, not the set. This is documented and expected behavior. Assuming you want to use update() for some reason, you could write your lambda as follows:

 lambda x, y: x.update(y) or x

The or clause returns x if the first clause is "falsy" (which None is).

Really, though, I think you want to use union() instead of update(). It does mostly the same thing and returns the result.

lambda x, y: x.union(y) 

BTW, you can just write set() to get an empty set, you don't need set([]). So the rewritten reduce() would be:

reduce(lambda x, y: x.union(y), a, set())

Others have posted additional options, each of which has value for making you think about how they work.

like image 43
kindall Avatar answered Sep 22 '22 01:09

kindall