python匿名函式(lambda)、函式引數(*args、**kwargs)、柯里化及生成器
1、匿名函式
通過lambda關鍵字進行定義,語句的結果就是返回值,如下所示:
In [32]: def sho_function(a):
...: return a**2
...:
In [33]: equiv = lambda a : a**2
In [34]: print(equiv(3))
9
2、函式的引數
python中,函式引數的工作方式是很簡單的,如編寫的函式function(a, b, c, d=some , e=value)時,位置和關鍵字引數分別被打包成元組和字典,函式實際接收到的是一個元組args和一個字典kwargs,自動在內部做如下轉換:
a, b, c = args
d = kwargs('d', d_default_value)
e = kwargs('e', e_default_value)
如下面的示例:
In [35]: def argsfunction(*args, **kwargs): ...: print('args is ',args) ...: print('kwargs is ',kwargs) ...: print('first value in args is ',args[0]) ...: print('key \'kw1\' value is' ,kwargs.get('kw1','java')) ...: In [36]: argsfunction(2, 4, kw1='thon', kw2='py') args is (2, 4) kwargs is {'kw1': 'thon', 'kw2': 'py'} first value in args is 2 key 'kw1' value is thon
3、柯里化:部分引數的應用
柯里化是指通過“部分引數應用”從現有函式派生出新函式的技術,如下面的應用:
In [37]: def add_number(x, y):
...: return x+y
...:
In [38]: add_five = lambda y : add_number(5, y)
In [39]: print(add_five(10))
15
add_number的第二個引數被稱為“柯里化的”,其實質就是定義了一個可以呼叫現有函式的新函式而已。內建的functools模組可以用partial函式將此過程簡化。如下所示:
In [1]: def add_numbers(x, y): ...: return x + y; ...: In [2]: from functools import partial In [3]: add_six = partial(add_numbers, 6) In [4]: print(add_six(10)) 16
4、 生成器
生成器(generator)是構造新的可迭代物件的一種簡單方式,一般的函式執行之後只會返回單個值,而生成器是以延遲的方式返回一個值序列,即每返回一個值之後暫停,直到下一個值被請求時再繼續。建立一個生成器,只需將函式中的return替換為yield即可,請看下面的示例:
In [5]: #函式
In [6]: def squares1(n=10):
...: print('generating squares from 1 to %d' % (n ** 2))
...: for i in range(1, n+1):
...: return i ** 2
...:
In [7]: sq1=squares1()
generating squares from 1 to 100
In [8]: #生成器
In [9]: def squares2(n=10):
...: print('generating squares from 1 to %d' % (n ** 2))
...: for i in range(1, n+1):
...: yield i ** 2
...:
In [10]: gen = squares2()
In [11]: gen
Out[11]: <generator object squares2 at 0x000001F35699D8E0>
In [12]: for x in gen:
...: print(x)
...:
generating squares from 1 to 100
1
4
9
16
25
36
49
64
81
100
生成器表示式(generator expression):是構造生成器的最簡單方式,生成器也有一個類似於列表、字典、集合推導式的東西,建立方式為:把列表推導式兩端的方括號(中括號)改成圓括號(小括號),如下所示:
In [13]: gen2 = (x ** 2 for x in range(100))
In [14]: gen2
Out[14]: <generator object <genexpr> at 0x000001F356A92CA8>
生成器表示式可用於任何接受生成器的python函式中,如下所示:
In [15]: sum (x ** 2 for x in range(100))
Out[15]: 328350
itertools模組:標準庫itertools模組中有一組用於常見資料演算法的生成器,比如groupby可以接受任何序列和一個函式,他根據函式的返回值對序列中的連續元素進行分組(注意是連續元素),所下面的例子:
In [16]: #itertools模組
...: import itertools
...: first_letter = lambda x:x[0]
...: names=['Alan', 'ABC', 'Test', 'Tom', 'ACT', 'Why']
...: for letter, names in itertools.groupby(names, first_letter):
...: print(letter, list(names))
...:
A ['Alan', 'ABC']
T ['Test', 'Tom']
A ['ACT']
W ['Why']
常見的itertools函式如下:
(1)imap(func, *iterables):內建函式map的生成器版,將func應用於引數序列的各個打包元組;
(2)ifilter(func, iterable):內建函式filter的生成器版,當func(x)為True時輸出元素x;
(3)combinations(iterable, k):生成一個由iterable中所有可能的k元元組構成的序列(不考慮順序);
(4)permutations(iterable, k):生成一個由iterable中所有可能的k元元組構成的序列(考慮順序);
(5)groupby(iterable[, keyfunc]):為每個唯一鍵生成一個(key, subitrator)。