gpt4 book ai didi

python - 减少字典值的并集会产生意外结果

转载 作者:行者123 更新时间:2023-11-28 22:17:05 25 4
gpt4 key购买 nike

我想合并所有字典值,在本例中是集合。只有当输入列表中正好有两个词典时,我才能得到预期的结果。
输入列表中的两个词典生成预期结果:

>>> 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期望dicts,但产生set。由于无法在x['y']上调用set,因此会引发TypeError
iterable只有两个元素时,function只应用一次并且只应用于这些元素。因此,永远不会遇到返回类型function不是有效输入类型的问题。
必须先从mapdict,然后sets。

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会失败
调用 set执行与此代码等效的操作:
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

这导致了几个案例:
reduce只有一个元素且未设置
reduce(function, iterable)iterablestart)的第一个元素
result从不被调用;它的返回和输入类型无关紧要
iterable有两个元素且未设置
1.functioniterable)的第一个元素
start在第一个元素和 result元素上调用( iterable
1.从不接收自己的结果;其返回类型没有意义
function有两个以上的元素且未设置
next2.function)的第一个元素
iterable在第一个元素和 start元素上调用( result
iterable是在前面的结果和 1.元素上调用的( function
next接收自己的结果;其返回类型和输入类型必须匹配
2.为空或不为空并且设置了 function
如果 next2.的第一个元素,则同上
function为空且未设置
无法设置 iterable,并引发 startstart
就你而言,就是:
两本字典是两本。并按预期工作。
三本字典等于三本。并阻塞不兼容的输入和返回类型。
空的输入列表是5。在缺少的输入上失败-正如预期的那样。
如何替代
映射/减少
实际上,您的 iterable同时做两件事:分别转换/提取每个元素,然后合并两个结果。这是一个经典的map/reduce任务:每个元素一个,所有元素一个。
您可以使用内置的 iterablestart将其直接分为两个单独的操作:
sets = map(lambda x: x['a'], [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}])
result = reduce(lambda x, y: x | y, sets)

当然,也可以直接嵌套这两个表达式。
理解/减少
result部分可以通过理解来表达。
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中,也可以使用赋值表达式来代替 TypeError
result = set()
result = [(result := (result | x['a'])) for x in [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}]]

使用for循环
只是,你知道,写出来。
result = set()
for element in [{'a': {1, 2}}, {'a': {3, 4}}, {'a': {5, 6}}]:
result |= element['a']

关于python - 减少字典值的并集会产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51630564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com