重定向对象列表以使用 lambda 减少函数时出错

Posted

技术标签:

【中文标题】重定向对象列表以使用 lambda 减少函数时出错【英文标题】:An error when redirecting a list of objects to reduce function with lambda 【发布时间】:2019-12-30 07:02:12 【问题描述】:

这是简单的代码。

class C:
  def __init__(self):
    self.l = [1,2,3]

a = C()
b = C()
c = C()

reduce(lambda x,y: x.l + y.l, [a,b,c])

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'list' object has no attribute 'l'

我知道还有其他几种方法。但我想看看为什么这不起作用。

输出应该与给出的相同

sum([x.l for x in [a,b,c]], [])

这是

[1, 2, 3, 1, 2, 3, 1, 2, 3]

【问题讨论】:

预期的结果是什么? x.l + y.l 生成一个列表,该列表将反馈到下一个 reduce 调用中。您的函数期望两个参数都是 C 对象。为此,您需要返回一个 C 对象。 This 代码运行,但可能无法执行您需要它执行的操作。 我期望的是sum([x.l for x in [a,b,c]], []) 那么,你的意思是这不能写成一个 lins 代码吗? 是的,它可能可以,但我只是将它作为一个函数,让我可以在其中放置打印语句。我的代码和答案的区别在于结果是一个C 对象。可能是你想要的,也可能不是。 【参考方案1】:

作为第一个参数传递给reduce的函数有2个参数,第一个是前一个reduction的结果(或者如果没有给出初始值,则为iterable中的第一项)。在您的情况下,在将前两个列表添加在一起之后,x 现在是一个列表,当传递给 lambda 以进行第二次迭代并且没有属性 l 因为它不是 C

如果您通过map 运行您的列表,您可以从所有对象中提取列表并将它们传递给reduce

reduce(lambda x, y: x + y, map(lambda z: z.l, [a,b,c]))

【讨论】:

明确答案!谢谢!【参考方案2】:

正如 Iain 在他的回答中所说,在评估第一个术语后问题就会出现,因为您的类型停止匹配。

Reduce 的形式为:reduce(f(B,A)-&gt;B, [A], optional B) -&gt; B

您提供了一个签名为f(C, C) -&gt; [int]的函数

reduce(lambda x,y: x.l + y.l, [a,b,c])

f(B,A)-&gt;B 不匹配。您可以通过更改第一个参数 (1) 或返回值 (2) 以两种方式明确解决此问题

(1)f(int, C) -&gt; int。其中 A 是 C,B 是 [int]。

reduce(lambda x, y: x + y.l, [a, b, c], [])

(2)f(C, C) --&gt; C。其中 A 是 C,B 也是 C。

def add_c(c1, c2):
    ret = C()
    ret.l = c1.l + c2.l
    return ret
reduce(add_c, [a, b, c]).l

注意.l 以提取您的列表

请注意,第二个是丑陋的,因为您的类非常愚蠢,并且没有 init。小写 L 作为变量也是不幸的。

【讨论】:

以上是关于重定向对象列表以使用 lambda 减少函数时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 header() 方法进行重定向时出错 [关闭]

使用 nginx 重定向 prometheus 调用时出错

将 packaged_task 对象移动到 lambda 捕获时出错

通过 AWS Lambda 和 CloudFront 重定向 URL

智能指针可以选择性地隐藏或重定向函数调用到它们包装的对象吗?

如何在 MFC 中重定向 TRACE 语句以减少来自 AfxDumpStack() 的数据流?