我看到這個在招聘廣告(上SO):解碼隱祕的Python聲明
lambda f: (lambda a: a(a))(lambda b: f(lambda *args: b(b)(*args)))
所以我的理解是它是一個匿名(未命名)功能,它是由另外兩個嵌套的匿名函數。最內層的函數需要一個變量列表(* args)。
我不知道該怎麼辦。如果沒有看到實際的參數列表,這是否會實際工作或不可能分辨?
我看到這個在招聘廣告(上SO):解碼隱祕的Python聲明
lambda f: (lambda a: a(a))(lambda b: f(lambda *args: b(b)(*args)))
所以我的理解是它是一個匿名(未命名)功能,它是由另外兩個嵌套的匿名函數。最內層的函數需要一個變量列表(* args)。
我不知道該怎麼辦。如果沒有看到實際的參數列表,這是否會實際工作或不可能分辨?
我已經取消了lambda,只是爲了讓它更容易閱讀。下面是一個使用嵌套函數的代碼:
def f1(f):
def f2(a):
return a(a)
def f3(b):
def f4(*args):
return b(b)(*args)
return f(f4)
return f2(f3)
這相當於基本上是:
現在讓我們跟隨函數調用。首先你會打電話給f1,並提供一些論據。那麼下面的事情發生:
因此F1可以簡化爲:
def f1(f):
def f3():
def f4(*args):
return f3()(*args)
return f(f4)
return f3()
現在我來了一個方法來調用F1不會在無限遞歸結束:
called = False
def g1(func):
def g2(*args):
print args
return None
global called
if not called:
called = True
func(5)
else:
return g2
f1(g1) # prints "(5,)"
正如你所看到的,它採用的是全球停止遞歸。
這裏有一個運行泊松分佈的試驗用的λ(拉姆達是泊松分佈,而不是拉姆達操作參數)的10又如:
import random
def g3(func):
def g4(a):
def g5(b):
print a
return a+b
return g5
if random.random() < 0.1:
return g4(1)
else:
return g4(func(1))
f1(g3)
最後的東西確定的,不依賴於一個全球性的,實際上有些有趣:
def g6(func):
def g7(n):
if n > 0:
return n*func(n-1)
else:
return 1
return g7
print f1(g6)(5) # 120
print f1(g6)(6) # 720
我敢肯定,每個人都可以猜到這個功能是什麼,但很有趣的是,其實你可以得到這個奇怪的lambda表達式做一些有用的東西。
'function'應該用'def'替換。 – falsetru
哇,是的,我在這裏很蠢 – CrazyCasta
你應該在'f2'之外但在'f1'之內定義'f3'。 – justhalf
不只是*指定參數時,這是很難說什麼是不知道什麼a
,b
,f
,和*args
是。
當b作爲參數傳遞給函數b時,兔子的洞變得特別深,並且這個結果是一個傳遞給args的函數。
該代碼正在創建Y-combinator in Python。這只是一個練習,而不是真實世界的代碼;不要試圖解密它。
要了解Y-combinator本身的功能,可以參考此SO問題:What is a y-combinator?及其wikipedia頁面:Fixed-point combinator。
也許這個廣告正在尋找知道函數式編程和/或高級計算機科學主題的人,如Lambda calculus和Combinatory logic,它們是函數式編程背後的主要理論基礎。
或者他們的公司是Y Combinator winner startup,他們只是在尋找具有CS背景的Python程序員。
這是相當相當的,沒有太多的嵌套:
def f1(f):
def f2(a): return a(a)
def f3(b):
def f4(*args): return b(b)(*args)
return f(f4)
return f2(f3)
f2
可以更換,所以我們得到
def f1(f):
def f3(b):
def f4(*args): return b(b)(*args)
return f(f4)
return f3(f3) # was f2(f3)
f3
總是與自身調用,所以我們用f3
替換b
:
def f1(f):
def f3():
def f4(*args): return f3()(*args)
return f(f4)
return f3()
它有什麼作用?
我們看到f3()
返回任何f
返回,並且這應該用任意數量的參數來調用。
f
應該採取另一種功能*args
並返回這樣的功能。
調用f1(f)
返回任何f(f4)
返回。
測試一下:
f=lambda ff: lambda *args: ff(*args)
,f1(f)()
給我們帶來了無限遞歸。f=lambda ff: lambda *args: (ff, args)
不會調用指定的函數,所以我們可以用它安全地玩耍:
f1(f)(4)
給了我們一個元組(f4, (4,))
。f1(f)(4)[0](1)
,我們得到(f4, (1,))
。
你確定它是*應該*做任何事嗎? –
我會第二@ mhlester的建議,這是一個生病的笑話。有可能導致無盡的遞歸?! – volcano
代碼的作用可能並不清楚,但很明顯,管理員必須做的事情是:啓動程序員並獲得編寫可讀代碼的人。 – Matthias