1. 程式人生 > >python匿名函式(lambda)、函式引數(*args、**kwargs)、柯里化及生成器

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)