1.python基礎要點(三)

注:本文主要轉載自廖雪峯的python教程,部分內容由自己編寫。

一、函數

(1)遞歸函數

定義:如果一個函數在內部調用自身本身,這個函數就是遞歸函數。


在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。

舉個例子,我們來計算階乘n! = 1 x 2 x 3 x ... x n,用函數fact(n)表示,可以看出:

fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

所以,fact(n)可以表示爲n x fact(n-1),只有n=1時需要特殊處理。

於是,fact(n)用遞歸的方式寫出來就是:

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

遞歸函數的優點是定義簡單,邏輯清晰。理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰。

使用遞歸函數需要注意防止棧溢出。在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。


二、高級特性

1、切片

L[1:3]

L[:3]
L[-2:-1]
以上均不取最後的索引值。

L[-2:]
以上取最後的索引值。

實操:

切片操作十分有用。我們先創建一個0-99的數列:

>>> L = list(range(100))
>>> L
[0, 1, 2, 3, ..., 99]

可以通過切片輕鬆取出某一段數列。比如前10個數:

>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

後10個數:

>>> L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

前11-20個數:

>>> L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

後第2-第11個數:L[-11:-1]


前10個數,每兩個取一個:

>>> L[:10:2]
[0, 2, 4, 6, 8]

所有數,每5個取一個:

>>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

甚至什麼都不寫,只寫[:]就可以原樣複製一個list:

>>> L[:]
[0, 1, 2, 3, ..., 99]

tuple也是一種list,唯一區別是tuple不可變。因此,tuple也可以用切片操作,只是操作的結果仍是tuple:

>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)

字符串'xxx'也可以看成是一種list,每個元素就是一個字符。因此,字符串也可以用切片操作,只是操作結果仍是字符串:

>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

2、迭代

只要作用於一個可迭代對象,for循環就可以正常運行,而我們不太關心該對象究竟是list還是其他數據類型。

迭代:for ... in ...

可迭代對象(不一定要有下標):list、turple、dict、字符串

對於dict來說,默認情況下迭代的是key值。如果想迭代的是value值,可以使用 【for value in d.values():】。如果要同時迭代key和value值,則要【for key,value in d.items():】

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
...     print(key)
...
a
c
b

由於字符串也是可迭代對象,因此,也可以作用於for循環:

>>> for ch in 'ABC':
...     print(ch)
...
A
B
C
檢測對象是否可迭代的辦法:

 from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代,還可檢驗元組:isinstance((1,2,3),Iterable)---True
True
>>> isinstance(123, Iterable) # 整數是否可迭代
False

用 enumerate函數來迭代list的i和value值

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C
上面的for循環裏,同時引用了兩個變量,在Python裏是很常見的。

如:

 for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print(x, y)
...
1 1
2 4
3 9

3、列表生成式

列表生成式:單層循環,雙層循環,條件過濾

L1 = ['Hello','World',18,'Apple',None]L2 = ???

期待輸出: ['hello','world','apple']

代碼:

In [46]:L1 = ['Hello','World',18,'Apple',None]

In [47]:L2 = [s for s in L1 if isinstance(s,str)]

In [48]: print (L2)['Hello','World','Apple']


疑惑:

字典是否可以有生成式?

4、生成器(generator)

一邊循環一邊計算的叫生成器。

類型:list生成器【用()代替[]的列表生成式格式便可生成】、yield函數形式

5、迭代器

可用於for循環(list,turple,dict,s,生成器等)的都是Iterable

可用於next()函數並不斷返回下一個值的是Iterator

但Iterable可通過調用Iter()函數來獲得一個Iterator

6、高階函數(函數式編程)

(1)lambda:

格式:

lambda 參數:返回值

eg:f=lambda x:x+2

適用場景:可用於定義簡單函數,提高效率

(2)map/reduce

map示例:

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

>>> b=list(map(lambda x:x+2,a))  #其中,a=[1,2,3]

reduce :用於遞歸計算。(適用reduce函數須從functools庫中調用)

PS:最後的調用是

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

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

示例 1/2:比方說對一個序列求和,就可以用reduce實現:

>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
from functools import reduce

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]

def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))     #將字符串形式變爲整數形式
調用:str2int(‘135’)

輸出:135


示例3:

reduce(lambda x,y:x*y,range(1,n+1))

(2)filter函數

filter()函數是一個過濾器。

示例1:

b=list(filter(lambda x:x>5 and x<8,range(10)))

使用filter函數首先需要一個返回值爲bool型的函數,如lambda x:x>5 and x<8定義了一個函數來判斷,結果可以是true、false兩種,最後再把挑出的true的元素組成列表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章