使用空集作为初始值减少

时间:2011-11-30 05:36:20

标签: python

我有一个列表列表,我想构建一个存在于所有子列表中的元素集。

示例:a = [[1,2],[2,3]]应该提供set([1,2,3])

我尝试过reduce(lambda x,y:x.update(y),a,set([]))但它引发AttributeError: 'NoneType'对象没有属性'update'

有人可以告诉我如何使用reduce功能吗?

6 个答案:

答案 0 :(得分:10)

根据要求:

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

另一种有趣的方式:

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

还有一个很酷:

>>> set.union(set(), *a)
set([1, 2, 3])

答案 1 :(得分:6)

问题是集合上的update()返回None,而不是集合。这是记录和预期的行为。假设您出于某种原因想要使用update(),可以按如下方式编写lambda:

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

如果第一个子句是“falsy”(or是),则x子句返回None

但是,我觉得你想使用union()代替update()。它的作用大致相同,并返回结果。

lambda x, y: x.union(y) 

顺便说一下,你可以写set()来获得一个空集,你不需要set([])。所以重写的reduce()将是:

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

其他人已经发布了其他选项,每个选项都有助于您思考它们的工作方式。

答案 2 :(得分:1)

有点已经回答了如何使用reduce()完成此任务,但我认为使用itertools.chain.from_iterable()执行此任务并不那么笨重:

import itertools

a = [[1, 2], [2, 3]]

print set(itertools.chain.from_iterable(a))

答案 3 :(得分:0)

使用

c =set();
reduce(lambda x,y:c.update(y),a,c)

它正在使用的一套。由于set([])。update不返回值,reduce函数使用上一次操作的返回值。它引发了一个Nonetype没有属性更新。

答案 4 :(得分:0)

set.update()的问题是返回Noneitertools ..必须有更好的解决方案。而且有!我认为这更清洁:

>>> a = [[1,2],[2,3]]
>>> reduce(lambda x, y: set(x) | set(y), a)
set([1, 2, 3])

注意: |在集合之间建立联盟。

答案 5 :(得分:0)

另一个有纯列表理解的人:

>>> a = [[1,2],[2,3]]
>>> set([item for sublist in a for item in sublist])
{1, 2, 3}

这是Making a flat list out of list of lists in Python的内容。