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中定義函式 涉及到狀態儲存,可以使用...