2 回答

TA貢獻(xiàn)1712條經(jīng)驗(yàn) 獲得超3個(gè)贊
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]
這看起來(lái)不對(duì)——為什么不使用數(shù)據(jù)呢?
下一個(gè):
lamb2 = lambda x, y: lamb1(min(data), max(data))
lamb2使用 2 個(gè)參數(shù)進(jìn)行調(diào)用lamb1- 的最小值和最大值data。從哪里來(lái)data的?為什么我們要將兩個(gè)參數(shù)傳遞給只需要一個(gè)參數(shù)的 lambda?
最后:
dummy = lambda path: lamb2
所以 dummy 是一個(gè) lambda,當(dāng)被調(diào)用時(shí),返回 lambda lamb2。您從不調(diào)用lamb2,因此您不能期望它返回值。如果你確實(shí)調(diào)用了lamb2,你會(huì)得到一個(gè)錯(cuò)誤。
很難思考和調(diào)試單行代碼,所以我們首先將其定義為常規(guī)函數(shù)。
def dummy(path):
lines = [int(x) for x in open(path, "r").readlines()]
smallest = min(lines)
largest = max(lines)
return (smallest, largest)
現(xiàn)在將每一行轉(zhuǎn)換為 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))
如果我設(shè)置data.txt為
100
23
2349
20
21
1
然后將其運(yùn)行為
dummy("data.txt")
我得到輸出:
(1, 2349)
請(qǐng)注意,我們?nèi)匀挥幸粋€(gè)錯(cuò)誤 - 我們沒(méi)有進(jìn)行適當(dāng)?shù)那謇怼N覀兇蜷_一個(gè)文件,但從未關(guān)閉它。由于 CPython 實(shí)現(xiàn)的引用計(jì)數(shù)機(jī)制,這通常不是問(wèn)題,但引用計(jì)數(shù)是一個(gè)實(shí)現(xiàn)細(xì)節(jié),其他實(shí)現(xiàn)不會(huì)這樣做。
要解決這個(gè)問(wèn)題,最好的方法是使用語(yǔ)句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)
但故意沒(méi)有“with表達(dá)”。Python 的設(shè)計(jì)初衷并不是鼓勵(lì)將所有內(nèi)容都塞進(jìn)一個(gè)大的單行表達(dá)式中。
如果我們想編寫大行話lambda并仍然進(jìn)行適當(dāng)?shù)那謇?,最接近?wèn)題精神的解決方案是定義一個(gè)助手:
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))
當(dāng)我們這樣做時(shí),我們最好f直接迭代,而不是構(gòu)建一個(gè)列表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))

TA貢獻(xiàn)1111條經(jīng)驗(yàn) 獲得超0個(gè)贊
此版本的代碼運(yùn)行每個(gè) lambda 并打印作為參數(shù)提供給它的文件的第一行。
我要做的主要事情是將 lambda 聲明包裝在另一組括號(hào)中??磥?lái)您認(rèn)為是一組會(huì)導(dǎo)致調(diào)用 lambda 的括號(hào),結(jié)果卻被視為 lambda 主體的一部分。在 lambda 周圍添加一組括號(hào)可以解決這個(gè)問(wèn)題。
然后我遇到了一個(gè)問(wèn)題,你的參數(shù)名稱實(shí)際上沒(méi)有意義,所以為了讓它做某事,我輸入了文字值。
最后,需要先調(diào)用最里面的 lambda,然后才能對(duì)其返回值(包含文件行的列表)進(jìn)行操作[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"))
結(jié)果:
Test file - Line #1
添加回答
舉報(bào)