我想对所有字典值(在这种情况下是集合)进行并集。如果输入列表中只有两个字典,我只会得到预期的结果。
输入列表中的两个词典会产生预期的结果:
>>> reduce((lambda x, y: x['a'] | y['a']), [{'a': {1, 2}}, {'a': {3, 4}}])
set([1, 2, 3, 4])
输入列表中的三个词典会产生TypeError。
预期结果: set([1, 2, 3, 4, 5, 6])
>>> reduce((lambda x, y: x['a'] | y['a']), [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
Traceback (most recent call last):
File "<input>", line 1, in <module>
reduce((lambda x, y: x['a'] | y['a']), [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
File "<input>", line 1, in <lambda>
reduce((lambda x, y: x['a'] | y['a']), [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
TypeError: 'set' object has no attribute '__getitem__'
一本词典输入列表中产生的字典,而不是一组。
预期结果: set([1, 2])
>>> reduce((lambda x, y: x['a'] | y['a']), [{'a': {1, 2}}])
{'a': set([1, 2])}
空的输入列表也会产生不同的TypeError。
预期结果: set([])
>>> reduce((lambda x, y: x['a'] | y['a']), [])
Traceback (most recent call last):
File "<input>", line 1, in <module>
reduce((lambda x, y: x['a'] | y['a']), [])
TypeError: reduce() of empty sequence with no initial value
我需要帮助来了解我在做什么错以及为什么会产生这些结果。
TLDR:
该reduce(function, iterable)
调用以递归方式应用于和先前结果的function
元素。这意味着的返回类型必须是有效的输入类型!iterable
function
function
期望dict
s但产生一个set
。由于不可能调用x['y']
a set
,TypeError
因此引发了a 。iterable
仅具有两个元素,function
仅应用一次且仅于这些元件。function
因此,永远不会遇到返回类型不是有效输入类型的问题。您必须首先map
从dict
到set
,然后 reduce
是set
s。
reduce(lambda x, y: x | y, map(lambda x: x['a'], [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}]))
# merge via reduce ^ convert via map ^
reduce
在某些情况下会失败调用reduce(function, iterable)
等效于以下代码:
def reduce(function, iterable, start=None):
result = next(iterable) if start is None else start # 1.
for element in iterable:
result = function(result, element) # 2.
return result
这导致几种情况:
iterable
具有一个元件和start
未设置
result
是iterable
(1.
) 的第一个元素
function
从不叫;它的返回和输入类型无关紧要iterable
具有两个元件和start
未设置
result
是第一个元素的iterable
(1.
)function
在第一个元素和next
element(2.
) 上调用
function
永远不会收到自己的结果;它的返回类型是没有意义的iterable
有两个以上的元素,并start
没有设置
result
是第一个元素的iterable
(1.
)function
在第一个元素和next
元素(2.
)上调用function
在上一个结果和next
元素(2.
) 上调用
function
得到自己的结果;其返回类型和输入类型必须匹配iterable
为空或不为空且start
已设置
start
是iterable
iterable
是空的,并start
没有设置
result
无法设置,并且TypeError
引发(1.
)您的情况是:
您reduce
实际上实际上是同时做两件事:它分别转换/提取每个元素,然后合并两个结果。那是一个经典的map / reduce任务:每个元素一个,所有元素一个。
您可以使用map
和reduce
内置函数将其直接分为两个单独的操作:
sets = map(lambda x: x['a'], [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
result = reduce(lambda x, y: x | y, sets)
当然,您也可以直接嵌套这两个表达式。
map
可以使用理解来表达该部分。
sets = (x['a'] for x in [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
result = reduce(lambda x, y: x | y, sets)
在Python3.8中,您也可以使用赋值表达式代替reduce
。
result = set()
result = [(result := (result | x['a'])) for x in [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}]]
只是,你知道,写出来。
result = set()
for element in [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}]:
result |= element['a']
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句