我有一个列表列表,我想构建一个存在于所有子列表中的元素集。
示例:a = [[1,2],[2,3]]
应该提供set([1,2,3])
我尝试过reduce(lambda x,y:x.update(y),a,set([]))但它引发AttributeError: 'NoneType'
对象没有属性'update'
有人可以告诉我如何使用reduce功能吗?
答案 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()
的问题是返回None
和itertools
..必须有更好的解决方案。而且有!我认为这更清洁:
>>> 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}