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}