python - Python:在 lambda 中使用 lambda 返回 lambda 对象
问题描述
我正在阅读一个在 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?
我究竟做错了什么?
解决方案
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
,所以你不能指望它返回一个值。如果你确实call 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))
推荐阅读
- c - 通过结构一到结构二访问数据?
- javascript - Angular 2 - 如何过滤选择
- typescript - TypeScript 如何检测始终到达或无法到达的代码块?
- java - 如何将字段标记为持久但未序列化?
- php - gRPC 一元调用中的“start_batch 调用不正确”
- postgresql - 如何让 PostgreSQL 接受文本作为枚举值
- excel - 使用 VBA 将 Excel 范围转换为 Outlook 正文 - 需要帮助才能添加默认签名
- python - 当我按下按键时,为什么我的精灵在 pygame 中没有移动?
- go - 如何将我的 AWS EC2 密钥对 PEM 文件加载到我的 terratest 脚本以执行 AWS EC2 SSH 连接验证
- permissions - 有没有办法为 Deno 中的子目录授予读取权限?