python基礎2.0

遞歸函數:函數內部調用自身自己python

def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

 使用遞歸函數的優勢是邏輯簡單清晰,缺點是過深的調用會致使棧溢出。git

尾遞歸優化:設計模式

def fact(n):
    return fact_iter(n, 1)

def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)

 

能夠看到,return fact_iter(num - 1, num * product)僅返回遞歸函數自己,num - 1num * product在函數調用前就會被計算,不影響函數調用。閉包

fact(5)對應的fact_iter(5, 1)的調用以下:函數

===> fact_iter(5, 1)
===> fact_iter(4, 5)
===> fact_iter(3, 20)
===> fact_iter(2, 60)
===> fact_iter(1, 120)
===> 120

 python的高級特性工具

1)切片優化

L[0:9:2]前10個數,每兩個取一個spa

2)迭代.net

for ... in設計

由於dict的存儲不是按照list的方式順序排列,因此,迭代出的結果順序極可能不同。

字典的迭代

默認狀況下,dict迭代的是key。若是要迭代value,能夠用for value in d.values(),若是要同時迭代key和value,能夠用for k, v in d.items()

因爲字符串也是可迭代對象,所以,也能夠做用於for循環:

>>> for ch in 'ABC': ... print(ch) ... A B C 

因此,當咱們使用for循環時,只要做用於一個可迭代對象,for循環就能夠正常運行,而咱們不太關心該對象到底是list仍是其餘數據類型。

3)列表生成式

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

 運用列表生成式,能夠快速生成list,能夠經過一個list推導出另外一個list,而代碼卻十分簡潔

生成器:

generator是很是強大的工具,在Python中,能夠簡單地把列表生成式改爲generator,也能夠經過函數實現複雜邏輯的generator。

要理解generator的工做原理,它是在for循環的過程當中不斷計算出下一個元素,並在適當的條件結束for循環。對於函數改爲的generator來講,遇到return語句或者執行到函數體最後一行語句,就是結束generator的指令,for循環隨之結束。

請注意區分普通函數和generator函數,普通函數調用直接返回結果:

>>> r = abs(6) >>> r 6 

generator函數的「調用」實際返回一個generator對象:

>>> g = fib(6)
>>> g
<generator object fib at 0x1022ef948> 

定義生成器:generator function

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

 生成式和生成器的區別

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

 迭代器:

直接做用於for循環的對象統稱爲可迭代對象:Iterable

 生成器不但能夠做用於for循環,還能夠被next()函數不斷調用並返回下一個值,直到最後拋出StopIteration錯誤表示沒法繼續返回下一個值了。 能夠被next()函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator

凡是可做用於for循環的對象都是Iterable類型;

凡是可做用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

集合數據類型如listdictstr等是Iterable但不是Iterator,不過能夠經過iter()函數得到一個Iterator對象。

高階函數:

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

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

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

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

 用lambda函數進一步簡化成:

from functools import reduce

DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def char2num(s):
    return DIGITS[s]

def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

 filter函數:

map()相似,filter()也接收一個函數和一個序列。和map()不一樣的是,filter()把傳入的函數依次做用於每一個元素,而後根據返回值是True仍是False決定保留仍是丟棄該元素

一個序列中的空字符串刪掉,能夠這麼寫:

def not_empty(s):
    return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
# 結果: ['A', 'B', 'C']

filter()這個高階函數,關鍵在於正確實現一個「篩選」函數。 注意到filter()函數返回的是一個Iterator,也就是一個惰性序列,因此要強迫filter()完成計算結果,須要用list()函數得到全部結果並返回lis 

def is_odd(n):
    return n % 2 == 1
 
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)

 sorted()也是一個高階函數。用sorted()排序的關鍵在於實現一個映射函數。

sorted函數:sorted(iterable,key,reverse)

其中iterable表示能夠迭代的對象,  key是一個函數,用來選取參與比較的元素,reverse則是用來指定排序是倒序仍是順序,reverse=true則是倒序,reverse=false時則是順序,默認時reverse=false

如下返回值都是單一的key值排列或者value值排列

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>>sorted(d.keys())
['Bob', 'Michael', 'Tracy']
>>>sorted(d.values())
[75, 85, 95]
>>>sorted(d)
['Bob', 'Michael', 'Tracy']#默認就是根據key值排序
>>>sorted(d,key=lambda x: d[x])#根據value值的大小對key排序
['Bob', 'Tracy', 'Michael']

 如下返回值是既包含key又包含value的列表,與上面的區別就是sorted的第一個參數不是d而是d.items(),d.items會把d變成一個可迭代對象.

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>>d.items()
dict_items([('Michael', 95), ('Bob', 75), ('Tracy', 85)])
>>>sorted(d.items(),key=lambda x : x[1])
[('Bob', 75), ('Tracy', 85), ('Michael', 95)]
>>>d = {'data1':3,'da':1,'dat':2,'data22':4,'aa':3,'ff':0}
>>>sorted(d.items(),key=lambda x :(x[1],x[0]))#對dict先根據value排序,value相等的根據key排序
[('ff', 0), ('da', 1), ('dat', 2), ('aa', 3), ('data1', 3), ('data22', 4)]
sorted(d.items())#根據key值對整個dict排序
[('aa', 3), ('da', 1), ('dat', 2), ('data1', 3), ('data22', 4), ('ff', 0)]

 

返回函數

高階函數除了能夠接受函數做爲參數外,還能夠把函數做爲結果值返回。

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

咱們在函數lazy_sum中又定義了函數sum,而且,內部函數sum能夠引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,這種稱爲「閉包(Closure)」的程序結構擁有極大的威力。 

閉包:

def 外層函數(參數):
    def 內層函數():
        print("內層函數執行", 參數)

    return 內層函數


內層函數的引用 = 外層函數("傳入參數")
內層函數的引用()

 匿名函數:

lambda x: x * x

裝飾器:https://blog.csdn.net/weixin_39541558/article/details/79972104

在面向對象(OOP)的設計模式中,decorator被稱爲裝飾模式。OOP的裝飾模式須要經過繼承和組合來實現,而Python除了能支持OOP的decorator外,直接從語法層次支持decorator。Python的decorator能夠用函數實現,也能夠用類實現。

decorator能夠加強函數的功能,定義起來雖然有點複雜,但使用起來很是靈活和方便。

偏函數:

functools.partial能夠建立一個新的函數,這個新函數能夠固定住原函數的部分參數,從而在調用時更簡單。

functools.partial就是幫助咱們建立一個偏函數的,不須要咱們本身定義int2(),能夠直接使用下面的代碼建立一個新的函數int2

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
相關文章
相關標籤/搜索