Python 以空集作为初始值进行约简

Python 以空集作为初始值进行约简,python,Python,我有一个列表,我想构建一个包含所有子列表中元素的集合 示例:a=[[1,2],[2,3]应给出集合([1,2,3]) 我尝试了reduce(lambda x,y:x.update(y),a,set([]),但它引发了AttributeError:'NoneType'对象没有属性“update” 有人能告诉我如何使用reduce函数执行此操作吗?问题是,集合上的update()返回的是None,而不是集合。这是记录在案的预期行为。假设出于某种原因您想使用update(),您可以按如下方式编写lam

我有一个列表,我想构建一个包含所有子列表中元素的集合

示例:
a=[[1,2],[2,3]
应给出
集合([1,2,3])

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


有人能告诉我如何使用reduce函数执行此操作吗?

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

 lambda x, y: x.update(y) or x
如果第一个子句是“falsy”(其中
None
是),则
子句返回
x

实际上,我认为您应该使用
union()
而不是
update()
。它执行大致相同的操作并返回结果

lambda x, y: x.union(y) 
顺便说一句,您只需编写
set()
即可获得一个空集,您不需要
set([])
。因此,重写的
reduce()
将是:

reduce(lambda x, y: x.union(y), a, set())
其他人发布了附加选项,每个选项都有助于让你思考它们是如何工作的。

使用

c =set();
reduce(lambda x,y:c.update(y),a,c)
这是你正在使用的一套。因为set([])。update不返回值,reduce函数使用上一个操作返回的值。它会引发一个无属性更新的非类型。

根据请求:

>>> 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])

Kindall已经回答了如何使用
reduce()
完成这项任务,但我认为使用
itertools.chain来完成这项任务不那么麻烦


set.update()
的问题是返回
None
itertools
。。必须有更好的解决办法。还有!我认为这是更干净的方式:

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

注意:
|
在集合之间进行并集。

和另一个纯列表理解的集合:

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

这就是问题所在。

@julio.alegria我的第一个版本使用了
,但在
reduce(lambda s,elems:s | elems,a,set())的上下文中它看起来像一个奇怪的分隔符。
。在我看来,它看起来像是将
elem,a,set()
从lambda表达式中分离出来的东西。修复上一个例子,应该有
set
而不是
s
。看看时间基准这里的事情是,
set。union
接受
*args
,所以你根本不需要
reduce
<代码>设置([])。联合(*a)
就是您所需要的。是的,这是一个进一步的改进,但我认为
reduce()
是一个要求。+1而且速度非常快!看看这里的基准测试,回答这里的时间基准测试
>>> a = [[1,2],[2,3]]
>>> set([item for sublist in a for item in sublist])
{1, 2, 3}