Python中的lambda和lambda有什麼區別

2021-03-26 11:42:37 字數 4139 閱讀 4333

1樓:天天不看

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 ***prehension的實現不同,list ***prehension的例子是不太恰當的。racket中的list ***prehension經過巨集後是遞迴的函式呼叫的形式,而類似的python**可能是這樣的:

map(lambda i: lambda n: i+n, range(10))[3](4)

這個時候python的行為和racket是一樣的。但對於list ***prehension而言,python並不是函式式語言(again),同haskell、scala、racket這些的實現是不同的,在***prehension的過程中並沒有建立出各自包含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。

2樓:梅載闞高翰

真正的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中map(lambda x: x % mydict, mylist)是什麼意思? 10

3樓:匿名使用者

其實這來句話,你應該理解

源map和lambda是什麼意思。

1. lambda生成匿名函式

2. map(func,seq) 就是將函式作用在序列的每個元素上,然後建立由函式返回值組成的列表。

3. map(lambda x: x % mydict, mylist),遍歷mylist每個元素,執行lambda函式,並返回乙個列表

4樓:匿名使用者

x是定義bai的變數用來遍歷

dumylist中的所有值zhi,mydict是任意的數dao,x%mydict就是mylist中的各個版數分別對mydict求餘。權

eg:mylist = [1,2,3,4]map(lambda x:x%3,mylist) -->result:[1,2,0,1]

5樓:匿名使用者

我估計復你的 mylist 是乙個list,裡製麵存的是格式化字bai

符串,而 mydict 則是乙個記du錄格式化字串中zhi所需要用到的引數dao資訊,比如類似於下面的**

mylist = ["my name is %(name)s", "and my age is %(age)d"]

mydict =

result = map(lambda x: x % mydict, mylist)

for s in result:

print s

就可以得到下面的列印

my name is tom

and my age is 13

另外一種可能,就是 mylist 裡存的是整數,而 mydict 是乙個整數,這樣了話,map語句是將 mylist 裡每乙個整數對 mydict 進行取餘操作,這個有點不太合理,沒必要對乙個整數命名成 mydict。

6樓:

這是乙個方程式,也就是將所有的元素,遍歷在函式上執行一遍,賦值給匿名函式

python中怎麼理解,python 中怎麼理解 new

這篇文章主要介紹了python中的 init 和 new 的區別和例項詳解它們的作用,需要的朋友可以參考下 一 init 方法是什麼?使用python寫過物件導向的 的同學,可能對 init 方法已經非常熟悉了,init 方法通常用在初始化乙個類例項的時候。例如 複製 如下 coding utf 8...

在Python中for迴圈和re sub怎麼一起用

在python中re是乙個常用的模組,主要是通過正規表示式進行字串處理。它的速度相對自己用 find,replace,split來說,通常更快。當然功能更強大。正規表示式也是一種語言,所以如果通過re.pile把它編譯成物件,會速度快很多。所以我們經常看到這樣的語句 exp re.pile s m ...

python定義函式,在python中定義函式

params 就是 5,5 5,2 就是2個5的元組,乘號可以理解成相加。30就是30個 的字串 params作為引數,前面的 號就是把params元組分解成元素的意思,這樣就分開成為2個引數了。實際上傳遞給了x,y 於是就執行了power 5,5 在python中定義函式 涉及到狀態儲存,可以使用...