1. 程式人生 > >【函數】02、匿名函數、生成器、高階函數

【函數】02、匿名函數、生成器、高階函數

lambda


一、匿名函數

1、定義

語法格式:

lambda args:expression

args:以逗號分隔的參數列表

expression:用到args中各參數的表達式

lambda定義的代碼必須是合法的表達式不能出現多條件語句(可使用if的三元表達式)和非表達式,如for和while等

lambda的首要用途是指定短小的回調函數

lambda將返回一個函數而不是將函數賦值給某變量名


In [77]: lambda x: x+1
Out[77]: <function __main__.<lambda>>

In [78]: f = lambda x: x+1

In [79]: type(f)
Out[79]: function

In [80]: f(1)
Out[80]: 2

In [81]: f(2)
Out[81]: 3


# 也可以直接使用小括號也調用匿名函數

In [88]: lambda x: x+1
Out[88]: <function __main__.<lambda>>

In [89]: (lambda x: x+1)               
Out[89]: <function __main__.<lambda>>

In [90]: (lambda x: x+1)(3)   # 第一個小括號用來改變優先級,第二個表示調用函數
Out[90]: 4


總結:

匿名函數使用lambda定義, lambda是一個表達式而非語句

匿名函數(lambda表達式)只能寫在一行上,所有也有人叫它單行函數

lamdba是一個單個表達式,而不是一個代碼塊

參數列表不需要使用小括號

冒號不是用來開啟新的語句塊,而是分隔參數列表和表達式

沒有return語句,最後一個表達式的值即為返回值

def語句創建的函數將賦值給某變量名,而lambda表達式直接返回函數

lambda也支持使用默認參數,關鍵字參數,可變參數,參數解構

In [130]: (lambda : 0)()
Out[130]: 0

In [131]: (lambda x: 0)(1)
Out[131]: 0

In [132]: (lambda x, y: x+y)(3, 5)
Out[132]: 8

In [133]: (lambda *args, **kwargs: print(args, kwargs)) (*range(3), **{str(x):x for x in range(3)})
(0, 1, 2) {‘0‘: 0, ‘1‘: 1, ‘2‘: 2}



匿名函數常用於高階函數中參數傳遞參數(當此函數參數非常短小時)

In [136]: 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.
(END) 


In [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8]
In [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8]

In [147]: sorted(lst)
Out[147]: [1, 2, 3, 4, 5, 6, 7, 8]

In [148]: sorted(lst, reverse=True)
Out[148]: [8, 7, 6, 5, 4, 3, 2, 1]


In [149]: lst == [1, 3, 5, "x", "xxj", "j", 2]
Out[149]: False

In [150]: lst = [1, 3, 5, "x", "xxj", "j", 2]

In [151]: sorted(lst)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-151-904d7ad462e2> in <module>()
----> 1 sorted(lst)

TypeError: ‘<‘ not supported between instances of ‘str‘ and ‘int‘

In [152]: lst.sort()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-152-e0fe8579802d> in <module>()
----> 1 lst.sort()

TypeError: ‘<‘ not supported between instances of ‘str‘ and ‘int‘


二、生成器

1、生成器函數

In [161]: def g():
     ...:     for x in range(10):
     ...:         yield x         # 表示彈出一個值
     ...:         

In [162]: r =g

In [163]: type(r)
Out[163]: function

In [164]: r = g()   # 此時函數已經執行完成了,函數講道理已經被銷毀了;但事實上沒有被銷毀
這是生成器函數和普通函數的區別

In [165]: type(r)
Out[165]: generator

In [166]: r
Out[166]: <generator object g at 0x7f7c20cdc938>


In [161]: def g():
     ...:     for x in range(10):
     ...:         yield x
     ...:         
     
In [169]: next(r)
Out[169]: 0

In [170]: next(r)
Out[170]: 1

In [171]: next(r)
Out[171]: 2

In [172]: next(r)
Out[172]: 3


生成器函數的工作過程:

In [174]: def gen():
     ...:     print(‘a‘)
     ...:     yield 1
     ...:     print(‘b‘)
     ...:     yield 2
     ...:     print(‘c‘)
     ...:     return 3
     ...:     

In [175]: g = gen()

In [176]: g
Out[176]: <generator object gen at 0x7f7c20cdc620>

In [177]: next(g)
a
Out[177]: 1

In [178]: next(g)
b
Out[178]: 2

In [185]: def gen():
     ...:     print(‘a‘)
     ...:     yield 1
     ...:     print(‘b‘)
     ...:     yield 2
     ...:     print(‘c‘)
     ...:     return 3
     ...:     

In [186]: g = gen()   # 執行生成器函數的時候,函數體並沒有被執行
  
In [187]: g
Out[187]: <generator object gen at 0x7f7c2025f938>

In [188]: next(g)    # 第一個next時,執行到第一個yield,停止執行
a
Out[188]: 1

In [189]: next(g)    # 第2個next時,從第1個yield之後開始執行到第2個yield,停止執行
b
Out[189]: 2

In [190]: next(g)    # 第3次next時,從第2個yield之後開始執行,當沒有更多yield時,拋出
StopIteration,異常的值是函數的返回值

c
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-190-5f315c5de15b> in <module>()
----> 1 next(g)

StopIteration: 3

In [197]: next(g)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-197-5f315c5de15b> in <module>()
----> 1 next(g)

StopIteration: 



In [193]: def gen():
     ...:     print(‘a‘)
     ...:     yield 1
     ...:     print(‘b‘)
     ...:     yield 2
     ...:     print(‘c‘)
     ...:     

In [194]: g = gen()

In [195]: next(g)
a
Out[195]: 1

In [196]: next(g)
b
Out[196]: 2

In [197]: next(g)
c
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-197-5f315c5de15b> in <module>()
----> 1 next(g)

StopIteration:       # 生成器函數沒有返回值時,StopIteration也沒有值


總結:

帶yield語句的函數稱之為生成器函數,生成器函數的返回值是生成器

生成器是特殊的叠代器

生成器函數執行的時候,不會執行函數體

當next生成器的時候,當前代碼執行到第一個yield,會彈出值,並暫停函數

當再次next生成器時,從上次暫停處開始往下執行到下一個yield

當沒有多余的yield的時候,會拋出StopIteration異常,異常的Value是函數的返回值







【函數】02、匿名函數、生成器、高階函數