lambda表達式


lambda表達式

  lambda表達式就是能嵌入到其他表達式當中的匿名函數(閉包)

意義:

1、可以在表達式當中直接定義一個函數,而不需要將定義函數和表達式分開,這個函數只是一個臨時的函數。
2、引入了閉包。基本上常見的支持lambda表達式的語言里,不存在不支持閉包的lambda表達式;從函數式編程的角度來說,支持閉包也是很重要的。
如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變量進行引用,那么內部函數就被認為是閉包(closure),它使你的lambda表達式從一個普通的函數變成了一個帶隱藏參數的函數。

創建語法:

lambda parameters:express

parameters:可選,如果提供,通常是逗號分隔的變量表達式形式,即位置參數。

expression:不能包含分支或循環(但允許條件表達式),也不能包含return(或yield)函數。如果為元組,則應用圓括號將其包含起來。

實例(實驗環境為Python3.6)

兩數求和:

#lambda
>>>my_lambda = lambda x,y;x+y
#執行
>>>result = my_lambda(1,2)
result=3

求n的階乘:

>>>n=5
>>>reduce(lambda x,y:x*y, range(1,n+1)
120

把lambda 作為返回表達式

>>> b=lambda x:lambda y:x+y
>>>a=b(3)
>>>a(2)
5
>>>(b(2))(2)
4

 

內建函數:(map,reduce,filter,sorted)

map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的list返回

(python3.6)

>>> list(map(lambda x:x*x,[1,2,3,4,5,6,7,8,9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce()把一個函數作用在一個序列[x1, x2, x3...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

比如上面的求階乘的代碼。

字符串str也是一個序列,我們可以寫一個吧str轉換成int的函數:(python3.6)

>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> from functools import reduce
>>> reduce(lambda x,y:x*10+y,map(char2num,'13579'))
13579

filter()函數接收一個函數 f 和一個list,這個函數 f 的作用是對每個元素進行判斷,返回 True或 False,filter()根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。

 寫一個從list[1,2,3,4,5,6]中刪除偶數,保留奇數的程序(Python3.6)

>>> list(filter(lambda x:x%2==1,[1,2,3,4,5,6]))
... 
[1, 3, 5]

排序函數 sorted()和list.sort[]

 python中,具體到對list進行排序的方法有倆,一個是list自帶的sort方法,這個是直接對list進行操作,只有list才包含的方法;另外一個是內建函數sorted方法,可以對所有可迭代的對象進行排序操作,在本質上,list的排序和內建函數sorted的排序是差不多的,連參數都基本上是一樣的

 主要的區別在於,list的sort方法返回的是對已經存在的列表進行操作,而內建函數sorted方法返回的是一個新的list,而不是在原來的基礎上進行的操作。

>>> help(sorted)
Help on built-in function sorted in module builtins:

sorted(iterable, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.

    A custom key function can be supplied to customize the sort order, and the
    reverse flag can be set to request the result in descending order.

Python3中去除了cmp內置函數,同時sorted等函數也去除了cmp關鍵字,添加key關鍵字 

使用sorted()方法和list.sort()方法進行排序
elements=[(2,12,"A"),(1,11,"N"),(1,3,"L"),(2,4,"B")]
>>> sorted(elements)
[(1, 3, 'L'), (1, 11, 'N'), (2, 4, 'B'), (2, 12, 'A')]
 
根據elements每個元組后兩項進行排序,e表示列表中每個三元組元素
在表達式是元組,且lambda為一個函數的參數時,lambda表達式的圓括號是必需的
>>> elements.sort(key=lambda e:(e[1],e[2]))
>>> elements
[(1, 3, 'L'), (2, 4, 'B'), (1, 11, 'N'), (2, 12, 'A')]
 
分片方式得到同樣的效果
>>> elements.sort(key=lambda e:e[1:3])
>>> elements
[(1, 3, 'L'), (2, 4, 'B'), (1, 11, 'N'), (2, 12, 'A')]
 
>>> elements.sort(key=lambda e:(e[2].lower(),e[1]))
以下兩種方法等價,都可以通過調用area(5,3),結果相同
>>> area=lambda b,h:0.5*b*h
>>> def area(b,h):
    return 0.5*b*h

閉包(簡單介紹一下閉包)

在一個內部函數中,對外部作用域的變量進行引用,(並且一般外部函數的返回值為內部函數),那么內部函數就被認為是閉包,舉個栗子(以一個類似棋盤游戲的例子來說明。假設棋盤大小為50*50,左上角為坐標系原點(0,0),我需要一個函數,接收2個參數,分別為方向(direction),步長(step),該函數控制棋子的運動。 這里需要說明的是,每次運動的起點都是上次運動結束的終點。):

>>> origin=[0,0]
>>> def create(pos=origin):
... def go(direction,step):
... new_x=pos[0]+direction[0]*step
... new_y=pos[1]+direction[1]*step
... pos[0]=new_x
... pos[1]=new_y
... return pos
... return go
...
>>> player = create()
>>> print(player([1,0],10))
[10, 0]
>>> print(player([0,1],20))
[10, 20]
>>> print(player([-1,0],10))
[0, 20]

>>>print('player:',player)

function: <function create.<locals>.go at 0x02F94660>

>>> print('function:',go)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'go' is not defined
>>> print('function:',create)
function: <function create at 0x02E4D540>

注意:

  • 閉包無法修改外部函數的局部變量
  • python循環中不包含域的概念
  • 閉包可以保存當前的運行環境

 

#
>>> def outerFunc():
...     x = 0
...     def innerFunc():
...             x = 1
...             print('inner x:',x)
...     print('outer x before call inner:',x)
...     innerFunc()
...     print('outer x after call inner:',x)
...
>>>
>>> outerFunc()
outer x before call inner: 0
inner x: 1
outer x after call inner: 0
>>>
#按照正常的理解下面的程序應該輸入0,2,4,對吧? 但實際輸出的是4,4,4,循環在Python中沒有遇到概念,flist在向列表中添加func的時候,並沒有保存i的值而當執行f(2)的時候才去取,這時候循環已經結束,i的值是2,所以結果都是4
>>> flist = []>>> for i in range(3):
...     def func(x):
...             return x*i
...     flist.append(func)
...
>>> for f in flist:
...     print(f(2))
...
4
4
4
#修改方案
>>> flist = []
>>> for i in range(3):
...     def makefunc(i):
...             def func(x):
...                     return x*i
...             return func
...     flist.append(makefunc(i))
...
>>> for f in flist:
...     print(f(2))
...
0
2
4
>>>
#(f是一個函數 序列) 在func外面再定義一個makefunc函數,func形成閉包

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM