python reduce来查找集合的联合

Cod*_*lus 12 python dictionary functional-programming set fold

我试图找到一组集合的联合.具体来说,我想要networkx调用图表字典中每个键的节点列表的并集periodic_gs.我想使用该reduce函数,因为似乎合理的是将所有periodic_gs[x].nodes() where 的联合作为x一个关键periodic_gs.

这是我的尝试:

reduce(lambda x,y: set(periodic_gs[x].nodes()).union(set(periodic_gs[y].nodes())), periodic_gs.keys(), {})
Run Code Online (Sandbox Code Playgroud)

对我而言,这表示在字典中的每个图形上使用节点的并集.出于某种原因,python告诉我:TypeError: unhashable type: 'dict'我没有看到这个TypeError,因为periodic_gs.keys()是一个键列表(它们是字符串,但我不知道这是多么重要),并且当替换为lambda函数的参数时将起作用.

是什么导致类型错误,我该如何解决?

Ash*_*ary 26

你可以set.union像这样使用:

>>> lis = [{1, 2, 3, 4}, {3, 4, 5}, {7, 3, 6}]
>>> set().union(*lis)
set([1, 2, 3, 4, 5, 6, 7])
Run Code Online (Sandbox Code Playgroud)

使用reduce:

>>> reduce(set.union, lis)
set([1, 2, 3, 4, 5, 6, 7])
Run Code Online (Sandbox Code Playgroud)

对于你的代码,这应该这样做:

set().union(*(x.nodes() for x in periodic_gs.values()))
reduce(set.union, (x.nodes() for x in periodic_gs.values()))
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 5

{}是一个空字典,而不是一个集合。用于set()创建一个空集。

然而,我认为你误解了reduce()这里的工作原理;x是 的前一个返回值lambday是序列中的下一个值。因为您返回一个集合,所以x这里始终是一个集合,并且您不能将其用作 的键periodic_gs

如果您想要图中所有节点的并集,请使用itertools.chain.from_iterable()set()

from itertools import chain

set(chain.from_iterable(periodic_gs[key].nodes() for key in periodic_gs))
Run Code Online (Sandbox Code Playgroud)

这会根据每个调用创建nodes()组。

要使用,reduce()您必须考虑到第一个参数始终是一个集合:

reduce(lambda res, key: res.union(periodic_gs[key].nodes()),  periodic_gs, set())
Run Code Online (Sandbox Code Playgroud)

我在这里假设它periodic_gs是可迭代的(产生键),就像普通字典一样;如果没有,请使用periodic_gs.keys().

使用常规词典的快速演示:

>>> example = {'foo': [1,2,3], 'bar': [3, 4, 1]}
>>> reduce(lambda res, key: res.union(example[key]), example, set())
set([1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)