为了账号安全,请及时绑定邮箱和手机立即绑定

Python:在 lambda 内部使用 lambda 返回 lambda 对象

Python:在 lambda 内部使用 lambda 返回 lambda 对象

慕哥9229398 2024-01-04 10:13:32
我正在阅读一个在 lambda 内部使用 lambda 的代码片段,然后我想通过创建一个从文件读取然后返回最大和最小数字的虚拟函数来测试它。这就是我想出的dummy = lambda path: (lambda x, y: (lambda data: ([y for x in open(path, "r").readline().splitlines() for y in x])[0])(min(data), max(data)))经过一点格式化,这就是它的样子(恕我直言,一行代码更具可读性。)dummy = lambda path: (    lambda x, y: (        lambda data: ([y for x in open(path, "r").readline().splitlines() for y in x])[            0        ]    )(min(data), max(data)))但它总是返回 lambda 对象Out: <function <lambda>.<locals>.<lambda> at 0x7fe26f00a4c0>或这个'function' object is not subscriptable; perhaps you missed a comma?我究竟做错了什么?
查看完整描述

2 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

dummy = lambda path: (

    lambda x, y: (

        lambda data: ([y for x in open(path, "r").readline().splitlines() for y in x])[

            0

        ]

    )(min(data), max(data))

)

让我们把它分成几行。


lamb1 = lambda data: ([y for x in open(path, "r").readline().splitlines() for y in x])[0] 

这看起来不对——为什么不使用数据呢?


下一个:


lamb2 = lambda x, y: lamb1(min(data), max(data))

lamb2使用 2 个参数进行调用lamb1- 的最小值和最大值data。从哪里来data的?为什么我们要将两个参数传递给只需要一个参数的 lambda?


最后:


dummy = lambda path: lamb2

所以 dummy 是一个 lambda,当被调用时,返回 lambda lamb2。您从不调用lamb2,因此您不能期望它返回值。如果你确实调用了lamb2,你会得到一个错误。


很难思考和调试单行代码,所以我们首先将其定义为常规函数。


def dummy(path):

    lines = [int(x) for x in open(path, "r").readlines()]

    smallest = min(lines)

    largest = max(lines)

    return (smallest, largest)

现在将每一行转换为 lambda:


readfile = lambda file: [int(x) for x in open(file, "r").readlines()]

minmax = lambda data: (min(data), max(data)

dummy = lambda path: minmax(readfile(path))

并加入这些 lambda:


dummy = lambda path: (lambda data: (min(data), max(data)))((lambda file: [int(x) for x in open(file, "r").readlines()])(path))

如果我设置data.txt为


100

23

2349

20

21

1

然后将其运行为


dummy("data.txt")

我得到输出:


(1, 2349)

请注意,我们仍然有一个错误 - 我们没有进行适当的清理。我们打开一个文件,但从未关闭它。由于 CPython 实现的引用计数机制,这通常不是问题,但引用计数是一个实现细节,其他实现不会这样做。


要解决这个问题,最好的方法是使用语句with:


def dummy(path):

    with open(path, 'r') as f:

        lines = [int(x) for x in f.readlines()]

    smallest = min(lines)

    largest = max(lines)

    return (smallest, largest)

但故意没有“with表达”。Python 的设计初衷并不是鼓励将所有内容都塞进一个大的单行表达式中。


如果我们想编写大行话lambda并仍然进行适当的清理,最接近问题精神的解决方案是定义一个助手:


def with_(resource, code):

    with resource as x:

        return code(x)

然后我们就可以翻译了


with open(path, 'r') as f:

    lines = [int(x) for x in f.readlines()]


lines = with_(open(path, 'r'), lambda f: [int(x) for x in f.readlines()])

并将其融入到我们的大话中,


dummy = lambda path: (lambda data: (min(data), max(data)))((lambda file: with_(open(path, 'r'), lambda f: [int(x) for x in f.readlines()]))(path))

当我们这样做时,我们最好f直接迭代,而不是构建一个列表readlines,然后迭代它:


dummy = lambda path: (lambda data: (min(data), max(data)))((lambda file: with_(open(path, 'r'), lambda f: [int(x) for x in f]))(path))



查看完整回答
反对 回复 2024-01-04
?
catspeake

TA贡献1111条经验 获得超0个赞

此版本的代码运行每个 lambda 并打印作为参数提供给它的文件的第一行。


我要做的主要事情是将 lambda 声明包装在另一组括号中。看来您认为是一组会导致调用 lambda 的括号,结果却被视为 lambda 主体的一部分。在 lambda 周围添加一组括号可以解决这个问题。


然后我遇到了一个问题,你的参数名称实际上没有意义,所以为了让它做某事,我输入了文字值。


最后,需要先调用最里面的 lambda,然后才能对其返回值(包含文件行的列表)进行操作[0]。


这将打印我为其提供路径的文本文件的第一行:


dummy = lambda path: (

    (lambda x, y: (

        (lambda data: ([y for x in open(path, "r").readline().splitlines() for y in x]))(3)[0]

    ))(1, 2)

)


print(dummy("/tmp/data.txt"))

结果:


Test file - Line #1


查看完整回答
反对 回复 2024-01-04
  • 2 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信