1樓:匿名使用者
lambda是用一句話來定義函式,可以用普通def代替
2樓:匿名使用者
是lambda演算的意思
python 中的 lambda 和lambda 有什麼區別
3樓:天天不看
python的lambda裡只能寫一行啦、不能有statement只能有expression啦,這些還是小問題,真正的問題是python對closure的實現根本是有缺陷的。閉包的實現都是錯誤的,哪來的真正的匿名函式?
比如在python2裡這樣的**是沒法執行的,
def counter():
count = 0
def inner():
count += 1
return count
return inner
c = counter()
print c()
python告訴你一個unboundlocalerror,count為什麼會unbound呢,因為closure沒有正確地實現。什麼是closure呢,closure是一個二元組:lambda(別管是有名字的還是沒名字的),和這個lambda定義時的environment。
而這個environment包含了lambda中的自由變數(比如這裡的count),這樣才把這個lambda『封閉』起來了,所以叫閉包。
我所理解的『真正的』的lambda是說:完整地支援higher-order function,即函式可以作為函式的引數,也可以作為函式的返回值,那怕引入了mutation。為了達到這一點,語言的實現需要正確地實現closure和lexical scope。
而mutation和lexical scope是兩個正交的概念,python因為有mutation而沒有完整實現lexical scope進而沒有完整地支援first-order function,這就叫broken lambda。python3裡新加的nonlocal關鍵字就是為了解決closure的歷史問題。
然而同樣的**在racket/scala/ocaml裡卻可以跑地歡快:
(define (counter)
(define count 0)
(define (inner)
(begin (set! count (add1 count))
count))
inner)
(define c (counter))
(c) ;1
(c) ;2
(c) ;3
def counter(): () => int =
inner
}val c = counter()
println(c())
println(c())
println(c())
let counter () =
let count = ref 0 in
let inner () =
count := !count + 1;
!count
in inner
;;let c = counter();;
print_int(c());
print_int(c());
print_int(c());
真正的lambda就是正確而完整地實現了lexical scope和closure的lambda。這就是python的lambda和『真正的』的lambda的區別。
當然python並不是函式式語言,python也從來沒有自我標榜是函式式語言,當年lambda都是一個lisp程式設計師給python加的,而且據說當時guido是強烈反對的……
btw,lambda這個名字確實沒什麼神祕的
===update:
經靈劍提醒,由於racket和python中對於list comprehension的實現不同,list comprehension的例子是不太恰當的。racket中的list comprehension經過巨集後是遞迴的函式呼叫的形式,而類似的python**可能是這樣的:
map(lambda i: lambda n: i+n, range(10))[3](4)
這個時候python的行為和racket是一樣的。但對於list comprehension而言,python並不是函式式語言(again),同haskell、scala、racket這些的實現是不同的,在comprehension的過程中並沒有建立出各自包含i的閉包。
原:比如這個python**:
fs = [(lambda n: i + n) for i in range(10)]
fs[3](4)
fs[3](4)應該是幾呢?python告訴你是13 = = 因為每一個lambda都share了相同的i。
同樣的**再看看racket裡呢:
(define fs
(for/list ([i (range 10)])
(λ (n) (+ i n))))
((fourth fs) 4)
racket里正確地告訴你結果是7。
4樓:梅載闞高翰
真正的lambda
就是沒有名字的函式,能做到任何普通函式能做到的事情,除了方便地遞迴呼叫自己。
python
因為本身設計思想,僅僅將
lambda
定位成一個輔助用的短函式,為了避免使用中為一些臨時的小**專門還要寫
def。
比如說對複雜的資料結構排序,要用函式選擇資料結構中排序的依據資料,那麼寫一個一次性的函式:
defselect(data):
return
data.array[0]
sorted(data,
key=select)
明顯累贅,lambda
的使用場所就是:
sorted(data,
key=lambda
x:x.array[0])
除類似此之外不提倡用
lambda,lambda
的侷限主要就是為了防止濫用。所以
lambda
只能寫一行,不能賦值,內部也不能定義等等等。
這就是python
的方**,雖然
python
也有常用的函式式工具,但是使用的時候必須要謹慎,不要因為賣弄聰明降低可讀性和效能。
另外對於問題補充,currying
是沒有支援的,而且這一堆都是函數語言程式設計的特性,匿名函式和它們是平級的,是函數語言程式設計特性的一部分,不存在從屬關係。。
python中的python中的問題
在python中,所有識別符號 可以包括英文 數字以及下劃線 但不能以數字開頭。python中的識別符號是區分大小寫的。這是知識背景 但是通常python的變成習慣以下劃線開頭的識別符號是有特殊意義的。以單下劃線開頭 foo 的代表不能直接訪問的類屬性,需通過類提供的介面進行訪問,不能用 from ...
python中與的區別,python 中 和 的差別
普通字串中沒有區別 如 abc 和 abc 是一樣的 如果字串中本身就有單引號或回雙引號,則要答使用另一種引號將該字串引起來才合法 如 he is a student he is a student 3.接著2說,如果字串中本身就有單引號或雙引號,還有一種合法的使用方式是,最外層使用的引號和字串的相...
python中header formats s怎麼解釋後面的字串
s 代表 輸入一個字元copy串,號代表左對齊 後補空白,號代表對齊寬度由輸入時確定 s 代表輸入一個字串,右對齊 前補空白,號代表對齊寬度由輸入時確定 s s 10,hello 15,world 等與 hello world 得 hello world 這是python 2.x的舊格式化寫法,py...