借著別人的文章(王圣元 [王的機器] )终吼,復(fù)盤一下python的基礎(chǔ)知識點。感謝原作者的分享氯哮!
一际跪、基本數(shù)據(jù)類型:整數(shù),浮點數(shù)喉钢,布爾
二姆打、容器數(shù)據(jù)類型:字符,元組肠虽,列表幔戏,字典,集合
三税课、條件語句和迭代循環(huán):If, If_else, Nested, While, For
四闲延、函數(shù):正規(guī)函數(shù),匿名函數(shù)韩玩,偏函數(shù)垒玲,柯里化
五、解析式:列表找颓,字典合愈,集合解析
對于任何一種計算機語言,我覺得最重要的就是「數(shù)據(jù)類型」「條件語句 & 迭代循環(huán)」和「函數(shù)」叮雳,這三方面一定要打牢基礎(chǔ)想暗。此外 Python 非常簡潔妇汗,一行代碼 (one-liner) 就能做很多事情帘不,很多時候都用了各種「解析式」,比如列表杨箭、字典和集合解析式寞焙。
在學(xué)習(xí)本貼前感受一下這個問題:如何把以下這個不規(guī)則的列表 a 里的所有元素一個個寫好,專業(yè)術(shù)語叫打平 (flatten)?
a = [1, 2, [3, 4], [[5, 6], [7, 8]]]
魔法來了 (這一行代碼有些長,用手機的建議橫屏看)
fn = lambda x: [y for l in x for y in fn(l)] if type(x) is list else [x]
[1, 2, 3, 4, 5, 6, 7, 8]
這一行代碼捣郊,用到了迭代辽狈、匿名函數(shù)、遞推函數(shù)呛牲、解析式這些技巧刮萌。初學(xué)者一看只會說“好酷啊,但看不懂”娘扩,看完本帖和下帖后着茸,我保證你會說“我也會這樣用了,真酷琐旁!”
1基本數(shù)據(jù)類型
Python 里面有自己的內(nèi)置數(shù)據(jù)類型 (build-in data type)涮阔,本節(jié)介紹基本的三種,分別是整型 (int)灰殴,浮點型 (float)敬特,和布爾型 (bool)。
1.1 整型
整數(shù) (integer) 是最簡單的數(shù)據(jù)類型牺陶,和下面浮點數(shù)的區(qū)別就是前者小數(shù)點后沒有值伟阔,后者小數(shù)點后有值。例子如下:
a = 1031 --1031 <class 'int'>
通過 print 的可看出 a 的值掰伸,以及類 (class) 是 int减俏。Python 里面萬物皆對象(object),「整數(shù)」也不例外碱工,只要是對象娃承,就有相應(yīng)的屬性 (attributes) 和方法 (methods)。
知識點
通過 dir( X ) 和help( X ) 可看出 X 對應(yīng)的對象里可用的屬性和方法怕篷。
- X 是 int历筝,那么就是 int 的屬性和方法
- X 是 float,那么就是 float 的屬性和方法
dir(int)
['__abs__','__add__',...'__xor__','bit_length','conjugate',...'real','to_bytes']
紅色的是 int 對象的可用方法廊谓,藍(lán)色的是 int 對象的可用屬性梳猪。對他們你有個大概印象就可以了,具體怎么用蒸痹,需要哪些參數(shù) (argument)春弥,你還需要查文檔〉看個bit_length的例子
a.bit_length() -- 11
該函數(shù)是找到一個整數(shù)的二進(jìn)制表示匿沛,再返回其長度。在本例中 a = 1031, 其二進(jìn)制表示為 ‘10000000111’ 榛鼎,長度為 11逃呼。
1.2 浮點型
簡單來說鳖孤,浮點型 (float) 數(shù)就是實數(shù), 例子如下:
print( 1, type(1) ) -- 1 <class 'int'>1.0 <class 'float'>
加一個小數(shù)點 . 就可以創(chuàng)建 float抡笼,不能再簡單苏揣。有時候我們想保留浮點型的小數(shù)點后 n 位⊥埔觯可以用 decimal 包里的 Decimal 對象和 getcontext() 方法來實現(xiàn)平匈。
import decimal
Python 里面有很多用途廣泛的包 (package),用什么你就引進(jìn) (import) 什么藏古。包也是對象吐葱,也可以用上面提到的dir(decimal) 來看其屬性和方法。比如 getcontext() 顯示了 Decimal 對象的默認(rèn)精度值是 28 位 (prec=28)校翔,展示如下:
decimal.getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999,Emax=999999, capitals=1, clamp=0, flags=[],traps=[InvalidOperation, DivisionByZero, Overflow])
讓我們看看 1/3 的保留 28 位長什么樣弟跑?
d = Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
那保留 4 位呢?用 getcontext().prec 來調(diào)整精度哦防症。
decimal.getcontext().prec = 4
Decimal('0.3333')
高精度的 float 加上低精度的 float孟辑,保持了高精度,沒毛病蔫敲。
d + e
Decimal('0.6666333333333333333333333333')
1.3 布爾型
布爾 (boolean) 型變量只能取兩個值饲嗽,**True **和 False。當(dāng)把布爾變量用在數(shù)字運算中奈嘿,用 1 和 0 代表 **True **和 False貌虾。
T = True
F = False
print( T + 2 ) -- 3
print( F - 8 ) --7
除了直接給變量賦值 **True **和 False,還可以用 bool(X) 來創(chuàng)建變量裙犹,其中 X 可以是
基本類型:整型尽狠、浮點型、布爾型
容器類型:字符叶圃、元組袄膏、列表、字典和集合
基本類型
print( type(0), bool(0), bool(1) ) --<class 'int'> False True
print( type(10.31), bool(0.00), bool(10.31) ) --<class 'float'> False True
print( type(True), bool(False), bool(True) ) --<class 'bool'> False True
bool 作用在基本類型變量的總結(jié):X 只要不是整型 0掺冠、浮點型 0.0沉馆,bool(X) 就是 True,其余就是 False德崭。
容器類型
print( type(''), bool( '' ), bool( 'python' ) ) --<class 'str'> False True
print( type(()), bool( () ), bool( (10,) ) ) --<class 'tuple'> False True
print( type([]), bool( [] ), bool( [1,2] ) ) --<class 'list'> False True
print( type({}), bool( {} ), bool( {'a':1, 'b':2} ) ) --<class 'dict'> False True
print( type(set()), bool( set() ), bool( {1,2} ) ) --<class 'set'> False True
bool 作用在容器類型變量的總結(jié):X 只要不是空的變量斥黑,bool(X) 就是 True,其余就是 False眉厨。
知識點
確定bool(X) 的值是 True 還是 False锌奴,就看 X 是不是空,空的話就是 False缺猛,不空的話就是True缨叫。
- 對于數(shù)值變量,0, 0.0 都可認(rèn)為是空的荔燎。
- 對于容器變量耻姥,里面沒元素就是空的。
2 容器數(shù)據(jù)類型
上節(jié)介紹的整型有咨、浮點型和布爾型都可以看成是單獨數(shù)據(jù)琐簇,而這些數(shù)據(jù)都可以放在一個容器里得到一個「容器類型」的數(shù)據(jù),比如:
- 字符 (str) 是一容器的字節(jié) char座享,注意 Python 里面沒有 char 類型的數(shù)據(jù)婉商,可以把單字符的 str 當(dāng)做 char。
- 元組 (tuple)渣叛、列表 (list)丈秩、字典 (dict) 和集合 (set) 是一容器的任何類型變量。
2.1 字符
字符用于處理文本 (text) 數(shù)據(jù)淳衙,用「單引號 ’」和「雙引號 “」來定義都可以蘑秽。
創(chuàng)建字符
t1 = 'i love Python!'
print( t1, type(t1) ) --i love Python! <class 'str'>
t2 = "I love Python!"
print( t2, type(t2) ) --I love Python! <class 'str'>
字符中常見的內(nèi)置方法 (可以用 dir(str) 來查) 有
- capitalize():大寫句首的字母
- split():把句子分成單詞
- find(x):找到給定詞 x 在句中的索引,找不到返回 -1
- replace(x, y):把句中 x 替代成 y
- strip(x):刪除句首或句末含 x 的部分
t1.capitalize() --'I love python!'
t2.split() --['I', 'love', 'Python!']
print( t1.find('love') ) -- 2
print( t1.find('like') ) -- 1
t2.replace( 'love Python', 'hate R' ) --'I hate R!'
print( 'http://www.python.org'.strip('htp:/') ) --www.python.org
print( 'http://www.python.org'.strip('.org') ) --http://www.python
索引和切片
s = 'Python'
print( s ) --Python
print( s[2:4] ) --th
print( s[-5:-2] ) --yth
print( s[2] ) --t
print( s[-1] ) --n
知識點
Python 里面索引有三個特點 (經(jīng)常讓人困惑):
- 從 0 開始 (和 C 一樣)箫攀,不像 Matlab 從 1 開始肠牲。
- 切片通常寫成 start:end 這種形式,包括「start 索引」對應(yīng)的元素靴跛,不包括「end索引」對應(yīng)的元素缀雳。因此 s[2:4] 只獲取字符串第 3 個到第 4 個元素。
- 索引值可正可負(fù)梢睛,正索引從 0 開始肥印,從左往右;負(fù)索引從 -1 開始绝葡,從右往左竖独。使用負(fù)數(shù)索引時,會從最后一個元素開始計數(shù)挤牛。最后一個元素的位置編號是 -1莹痢。
正則表達(dá)式
正則表達(dá)式 (regular expression) 主要用于識別字符串中符合某種模式的部分,什么叫模式呢墓赴?用下面一個具體例子來講解竞膳。
input = """
'06/18/2019 13:00:00', 100, '1st';
'06/18/2019 13:30:00', 110, '2nd';
'06/18/2019 14:00:00', 120, '3rd'
"""
假如你想把上面字符串中的「時間」的模式來抽象的表示出來,對照著具體表達(dá)式 '06/18/2019 13:00:00' 來看诫硕,我們發(fā)現(xiàn)該字符串有以下規(guī)則:
- 開頭和結(jié)束都有個單引號 '
- 里面有多個 0-9 數(shù)字
- 里面有多個正斜線 / 和分號 :
- 還有一個空格
因此我們用下面這樣的模式
pattern = re.compile("'[0-9/:\s]+'")
再看這個抽象模式表達(dá)式 '[0-9/:\s]+'坦辟,里面符號的意思如下:
- 最外面的兩個單引號 ' 代表該模式以它們開始和結(jié)束
- 中括號 [] 用來概括該模式涵蓋的所有類型的字節(jié)
- 0-9 代表數(shù)字類的字節(jié)
- / 代表正斜線
- : 代表分號
- \s 代表空格
- [] 外面的加號 + 代表 [] 里面的字節(jié)出現(xiàn)至少 1 次
有了模式 pattern,我們來看看是否能把字符串中所有符合 pattern 的日期表達(dá)式都找出來章办。
pattern.findall(input)
["'06/18/2019 13:00:00'",
"'06/18/2019 13:30:00'",
"'06/18/2019 14:00:00'"]
結(jié)果是對的锉走,之后你想怎么盤它就是你自己的事了滨彻,比如把 / 換成 -,比如用 datetime 里面的 striptime() 把日期里年挪蹭、月亭饵、日、小時梁厉、分鐘和秒都獲取出來辜羊。
2.2元組
創(chuàng)建元組
「元組」定義語法為 : (元素1, 元素2, ..., 元素n)
關(guān)鍵點是「小括號 ()」和「逗號 ,」
- 小括號把所有元素綁在一起
- 逗號將每個元素一一分開
創(chuàng)建元組的例子如下:
t1 = (1, 10.31, 'python')
t2 = 1, 10.31, 'python'
print( t1, type(t1) ) --(1, 10.31, 'python') <class 'tuple'>
print( t2, type(t2) ) --(1, 10.31, 'python') <class 'tuple'>
知識點
創(chuàng)建元組可以用小括號 (),也可以什么都不用词顾,為了可讀性八秃,建議還是用 ()。此外對于含單個元素的元組肉盹,務(wù)必記住要多加一個逗號昔驱,舉例如下:
print( type( ('OK') ) ) --<class 'str'>
print( type( ('OK',) ) --<class 'tuple'>
看看,沒加逗號來創(chuàng)建含單元素的元組上忍,Python 認(rèn)為它是字符舍悯。
當(dāng)然也可以創(chuàng)建二維元組:
nested = (1, 10.31, 'python'), ('data', 11)
nested --((1, 10.31, 'python'), ('data', 11))
索引和切片
元組中可以用整數(shù)來對它進(jìn)行索引 (indexing) 和切片 (slicing),不嚴(yán)謹(jǐn)?shù)闹v睡雇,前者是獲取單個元素萌衬,后者是獲取一組元素。接著上面二維元組的例子它抱,先看看索引的代碼:
nested[0] --(1, 10.31, 'python')
print( nested[0][0], nested[0][1], nested[0][2] ) --1 10.31 python
再看看切片的代碼:
nested[0][0:2] --(1, 10.31)
不可更改
元組有不可更改 (immutable) 的性質(zhì)秕豫,因此不能直接給元組的元素賦值,例子如下 (注意「元組不支持元素賦值」的報錯提示)观蓄。
t = ('OK', [1, 2], True)
t[2] = False --TypeError: 'tuple' object does not support item assignment
但是只要元組中的元素可更改 (mutable)混移,那么我們可以直接更改其元素,注意這跟賦值其元素不同侮穿。如下例 t[1] 是列表歌径,其內(nèi)容可以更改,因此用 append 在列表后加一個值沒問題亲茅。
t[1].append(3) --('OK', [1, 2, 3], True)
內(nèi)置方法
元組大小和內(nèi)容都不可更改回铛,因此只有 count 和 index 兩種方法。
t = (1, 10.31, 'python')
print( t.count('python') ) --1
print( t.index(10.31) ) --1
這兩個方法返回值都是 1克锣,但意思完全不同
- count('python') 是記錄在元組 t 中該元素出現(xiàn)幾次茵肃,顯然是 1 次
- index(10.31) 是找到該元素在元組 t 的索引,顯然是 1
元組拼接
元組拼接 (concatenate) 有兩種方式袭祟,用「加號 +」和「乘號 *」验残,前者首尾拼接,后者復(fù)制拼接巾乳。
(1, 10.31, 'python') + ('data', 11) + ('OK',) --(1, 10.31, 'python', 'data', 11, 'OK')
(1, 10.31, 'python') * 2 --(1, 10.31, 'python', 1, 10.31, 'python')
解壓元組
解壓 (unpack) 一維元組 (有幾個元素左邊括號定義幾個變量)
t = (1, 10.31, 'python')
(a, b, c) = t
print( a, b, c ) --1 10.31 python
解壓二維元組 (按照元組里的元組結(jié)構(gòu)來定義變量)
t = (1, 10.31, ('OK','python'))
(a, b, (c,d)) = t
print( a, b, c, d ) --1 10.31 OK python
如果你只想要元組其中幾個元素您没,用通配符「*」鸟召,英文叫 wildcard,在計算機語言中代表一個或多個元素氨鹏。下例就是把多個元素丟給了 rest 變量欧募。
t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print( a, b, c ) -- 1 2 5
print( rest ) --[3, 4]
如果你根本不在乎 rest 變量,那么就用通配符「*」加上下劃線「_」喻犁,劉例子如下:
a, b, *_ = t
print( a, b ) --1 2
優(yōu)點缺點
優(yōu)點:占內(nèi)存小槽片,安全何缓,創(chuàng)建遍歷速度比列表快肢础,可一賦多值。
缺點:不能添加和更改元素碌廓。
2.3列表
創(chuàng)建列表
「列表」定義語法為 : [元素1, 元素2, ..., 元素n]
關(guān)鍵點是「中括號 []」和「逗號 ,」
- 中括號把所有元素綁在一起
- 逗號將每個元素一一分開
創(chuàng)建列表的例子如下:
l = [1, 10.31,'python']
print(l, type(l)) --[1, 10.31, 'python'] <class 'list'>
內(nèi)置方法
不像元組传轰,列表內(nèi)容可更改 (mutable),因此附加 (append, extend)谷婆、插入 (insert)慨蛙、刪除 (remove, pop) 這些操作都可以用在它身上。
附加
l.append([4, 3])
print( l ) --[1, 10.31, 'python', [4, 3]]
l.extend([1.5, 2.0, 'OK'])
print( l ) --[1, 10.31, 'python', [4, 3], 1.5, 2.0, 'OK']
嚴(yán)格來說 append 是追加纪挎,把一個東西整體添加在列表后期贫,而 extend 是擴展,把一個東西里的所有元素添加在列表后异袄。對著上面結(jié)果感受一下區(qū)別通砍。
插入
l.insert(1, 'abc') # insert object before the index position
print(l) --[1, 'abc', 10.31, 'python', [4, 3], 1.5, 2.0, 'OK']
insert(i, x) 在編號 i 位置前插入 x。對著上面結(jié)果感受一下烤蜕。
刪除
l.remove('python') # remove first occurrence of object
print(I) --[1, 'abc', 10.31, [4, 3], 1.5, 2.0, 'OK']
p = l.pop(3) # removes and returns object at index. Only only pop 1 index position at any time.
print( p ) --[4, 3]
print( l ) --[1, 'abc', 10.31, 1.5, 2.0, 'OK']
remove 和 pop 都可以刪除元素
- 前者是指定具體要刪除的元素封孙,比如 'python'
- 后者是指定一個編號位置,比如 3讽营,刪除 l[3] 并返回出來
對著上面結(jié)果感受一下虎忌,具體用哪個看你需求。
切片索引
l = [7, 2, 999, 1000, 1, 3, 7, 2, 0, 1]
print( l ) --[7, 2, 999, 1000, 1, 3, 7, 2, 0, 1]
print( l[1:5:2] ) --[2, 1000]
print( l[:5:2] ) --[7, 999, 1]
print( l[1::2] ) --[2, 1000, 3, 2, 1]
print( l[::2] ) --[7, 999, 1, 7, 0]
print( l[::-1] ) --[1, 0, 2, 7, 3, 1, 1000, 999, 2, 7]
列表拼接
和元組拼接一樣橱鹏, 列表拼接也有兩種方式膜蠢,用「加號 +」和「乘號 *」,前者首尾拼接莉兰,后者復(fù)制拼接狡蝶。
[1, 10.31, 'python'] + ['data', 11] + ['OK'] --[1, 10.31, 'python', 'data', 11, 'OK']
[1, 10.31, 'python'] * 2 --[1, 10.31, 'python', 1, 10.31, 'python']
優(yōu)點缺點
優(yōu)點:靈活好用,可索引贮勃、可切片贪惹、可更改、可附加寂嘉、可插入奏瞬、可刪除枫绅。
缺點:相比 tuple 創(chuàng)建和遍歷速度慢,占內(nèi)存硼端。此外查找和插入時間較慢并淋。
2.4字典
創(chuàng)建字典
「字典」定義語法為 : {元素1, 元素2, ..., 元素n}
其中每一個元素是一個「鍵值對」- 鍵:值 (key:value)
關(guān)鍵點是「大括號 {}」,「逗號 ,」和「分號 :」
- 大括號把所有元素綁在一起
- 逗號將每個鍵值對一一分開
- 分號將鍵和值分開
創(chuàng)建字典的例子如下:
d = {
'Name' : 'Tencent',
'Country' : 'China',
'Industry' : 'Technology',
'Code': '00700.HK',
'Price' : '361 HKD'
}
print( d, type(d) )
{'Name': 'Tencent', 'Country': 'China',
'Industry': 'Technology', 'Code': '00700.HK',
'Price': '361 HKD'} <class 'dict'>
內(nèi)置方法
字典里最常用的三個內(nèi)置方法就是 keys(), values() 和 items(),分別是獲取字典的鍵珍昨、值县耽、對。
print( list(d.keys()) ) --['Name', 'Country', 'Industry', 'Code', 'Price', 'Headquarter']
print( list(d.values())) -- ['Tencent', 'China', 'Technology', '00700.HK', '359 HKD', 'Shen Zhen']
print( list(d.items()) ) -- [('Name', 'Tencent'), ('Country', 'China'), ('Industry', 'Technology'), ('Code', '00700.HK'), ('Price', '359 HKD'), ('Headquarter', 'Shen Zhen')]
此外在字典上也有添加镣典、獲取兔毙、更新、刪除等操作兄春。
添加
比如加一個「總部:深圳」
d['Headquarter'] = 'Shen Zhen'
d --{'Name': 'Tencent', 'Country': 'China',
'Industry': 'Technology', 'Code': '00700.HK',
'Price': '361 HKD', 'Headquarter': 'Shen Zhen'}
獲取
比如想看看騰訊的股價是多少 (兩種方法都可以)
print( d['Price'] ) --359 HKD359 HKD
更新
比如更新騰訊的股價到 359 港幣
d['Price'] = '359 HKD'
刪除
比如去掉股票代碼 (code)
del d['Code']
或像列表里的 pop() 函數(shù)澎剥,刪除行業(yè) (industry) 并返回出來。
print( d.pop('Industry') )
d
Technology
{'Name': 'Tencent',
'Country': 'China',
'Price': '359 HKD',
'Headquarter': 'Shen Zhen'}
不可更改鍵
字典里的鍵是不可更改的赶舆,因此只有那些不可更改的數(shù)據(jù)類型才能當(dāng)鍵哑姚,比如整數(shù) (雖然怪怪的)、浮點數(shù) (雖然怪怪的)芜茵、布爾 (雖然怪怪的)叙量、字符、元組 (雖然怪怪的)九串,而列表卻不行绞佩,因為它可更改。
那么如何快速判斷一個數(shù)據(jù)類型 X 是不是可更改的呢蒸辆?兩種方法:
麻煩方法:用 id(X) 函數(shù)征炼,對 X 進(jìn)行某種操作,比較操作前后的 id躬贡,如果不一樣谆奥,則 X 不可更改,如果一樣拂玻,則 X 可更改酸些。
便捷方法:用 hash(X),只要不報錯檐蚜,證明 X 可被哈希魄懂,即不可更改,反過來不可被哈希闯第,即可更改市栗。
先看用 id() 函數(shù)的在整數(shù) i 和列表 l 上的運行結(jié)果:
i = 1
print( id(i) ) --1607630928
i = i + 2
print( id(i) ) --1607630992
l = [1, 2]
print( id(l) ) --2022027856840
l.append('Python')
print( id(l) ) --2022027856840
- 整數(shù) i 在加 1 之后的 id 和之前不一樣,因此加完之后的這個 i (雖然名字沒變),但是不是加前的那個 i 了填帽,因此整數(shù)是不可更改的蛛淋。
- 列表 l 在附加 'Python' 之后的 id 和之前一樣,因此列表是可更改的篡腌。
先看用 hash() 函數(shù)的在字符 s褐荷,元組 t 和列表 l 上的運行結(jié)果:
hash('Name') --7230166658767143139
hash( (1,2,'Python') ) --3642952815031607597
hash( [1,2,'Python'] ) --TypeError: unhashable type: 'list'
字符 s 和元組 t 都能被哈希,因此它們是不可更改的嘹悼。列表 l 不能被哈希叛甫,因此它是可更改的。
優(yōu)點缺點
優(yōu)點:查找和插入速度快
缺點:占內(nèi)存大
2.5集合
創(chuàng)建集合
「集合」有兩種定義語法杨伙,第一種是: {元素1, 元素2, ..., 元素n}
關(guān)鍵點是「大括號 {}」和「逗號 ,」
- 大括號把所有元素綁在一起
- 逗號將每個元素一一分開
第二種是用 set() 函數(shù)其监,把列表或元組轉(zhuǎn)換成集合。
set( **列表 **或 元組 )
創(chuàng)建集合的例子如下 (用兩者方法創(chuàng)建 A 和 B):
A = set(['u', 'd', 'ud', 'du', 'd', 'du'])
B = {'d', 'dd', 'uu', 'u'}
print( A ) --{'d', 'du', 'u', 'ud'}
print( B ) --{'d', 'du', 'u', 'ud'}
從 A 的結(jié)果發(fā)現(xiàn)集合的兩個特點:無序 (unordered) 和唯一 (unique)缀台。由于 set 存儲的是無序集合棠赛,所以我們沒法通過索引來訪問,但是可以判斷一個元素是否在集合中。
B[1] --TypeError: 'set' object does not support indexing
'u' in B --True
內(nèi)置方法
用 set 的內(nèi)置方法就把它當(dāng)成是數(shù)學(xué)上的集脏款,那么并集俱笛、交集、差集都可以玩通了审丘。
并集 OR
print( A.union(B) ) # All unique elements in A or B
--{'uu', 'dd', 'd', 'u', 'du', 'ud'}
print( A | B ) # A OR B
--{'uu', 'dd', 'd', 'u', 'du', 'ud'}
交集 AND
print( A.intersection(B) ) # All elements in both A and B
--{'d', 'u'}
print( A & B ) # A AND B
--{'d', 'u'}
差集 A - B
print( A.difference(B) ) # Elements in A but not in B
--{'ud', 'du'}
print( A - B ) # A MINUS B
--{'ud', 'du'}
差集 B - A
print( B.difference(A) ) # Elements in B but not in A
--{'uu', 'dd'}
print( B - A ) # B MINUS A
--{'uu', 'dd'}
對稱差集 XOR
print( A.symmetric_difference(B) ) # All elements in either A or B, but not both
--{'ud', 'du', 'dd', 'uu'}
print( A ^ B ) # A XOR B
--{'ud', 'du', 'dd', 'uu'}
優(yōu)點缺點
優(yōu)點:不用判斷重復(fù)的元素
缺點:不能存儲可變對象
你看集合的「唯一」特性還不是雙刃劍,既可以是優(yōu)點,又可以是缺點勘天,所有東西都有 trade-off 的,要不然它就沒有存在的必要了捉邢。
3條件語句 & 迭代循環(huán)
在編寫程序時脯丝,我們要
- 在不同條件下完成不同動作,條件語句 (conditional statement) 賦予程序這種能力伏伐。
- 重復(fù)的完成某些動作宠进,迭代循環(huán) (iterative loop) 賦予程序這種能力。
3.1條件語句
條件語句太簡單了藐翎,大體有四種格式
- if 語句
- if-else 語句
- if-elif-else 語句
- nested 語句
3.1.1 if 語句
給定二元條件材蹬,滿足做事,不滿足不做事吝镣。
if x > 0:
print( 'x is positive' )
3.1.2 if-else 語句
給定二元條件堤器,滿足做事 A,不滿足做事 B末贾。
if x % 2 == 0:
print( 'x is even' )
else :
print( 'x is odd' )
3.1.3 if-elif-else 語句
給定多元條件闸溃,滿足條件 1 做事 A1,滿足條件 2 做事 A2,..., 滿足條件 n 做事 An辉川。直到把所有條件遍歷完掂为。
f x < y:
print( 'x is less than y' )
elif x > y:
print( 'x is greater than y' )
else:
print( 'x and y are equal' )
4. nested 語句
給定多元條件,滿足條件 1 做事 A1员串,不滿足就
滿足條件 2 做事 A2勇哗,不滿足就
...
直到把所有條件遍歷完。
if x == y:
print( 'x and y are equal' )
else:
if x < y:
print( 'x is less than y' )
else:
print( 'x is greater than y' )
3.2 迭代循環(huán)
對于迭代循環(huán)寸齐,Python 里面有「while 循環(huán)」和「for 循環(huán)」欲诺,沒有「do-while 循環(huán)」。
3.2.1 while 循環(huán)
n = 5
while n > 0:
print(n)
n = n-1
print('I love Python')
5
4
3
2
1
I love Python
While 循環(huán)非常簡單渺鹦,做事直到 while 后面的語句為 False扰法。上例就是打印從 n (初始值為 5) 一直到 1,循環(huán)執(zhí)行了 5 次毅厚。
一般來說塞颁,在 「while 循環(huán)」中,迭代的次數(shù)事先是不知道的吸耿,因為通常你不知道 while 后面的語句從 True 變成 False了祠锣。
3.2.2 for 循環(huán)
更多時候我們希望事先直到循環(huán)的次數(shù),比如在列表咽安、元組伴网、字典等容器類數(shù)據(jù)上遍歷一遍,在每個元素層面上做點事情妆棒。這時候就需要「for 循環(huán)」了澡腾。
languages = ['Python', 'R', 'Matlab', 'C++']
for language in languages:
print( 'I love', language )
print( 'Done!' )
I love Python
I love R
I love Matlab
I love C++
Done
讀讀 Python 里面的「for 循環(huán)」是不是很像讀英文。通用形式的 for loop 如下
for a in A
do something with a
其中 for和 in 是關(guān)鍵詞糕珊,A 是個可迭代數(shù)據(jù) (list, tuple, dic, set)动分,a 是 A 里面的每個元素.
回到具體例子,for loop 里面的 language 變量在每次循環(huán)中分別取值 Python, R, Matlab 和 C++红选,然后被打印澜公。
最后介紹一個稍微有點特殊的函數(shù) enumerate(),和 for loop 一起用的語法如下
for i, a in enumerate(A)
do something with a
發(fā)現(xiàn)區(qū)別了沒纠脾?用 enumerate(A) 不僅返回了 A 中的元素玛瘸,還順便給該元素一個索引值 (默認(rèn)從 0 開始)。此外苟蹈,用 enumerate(A, j) 還可以確定索引起始值為 j糊渊。 看下面例子。
languages = ['Python', 'R', 'Matlab', 'C++']
for i, language in enumerate(languages, 1):
print( i, 'I love', language )
print( 'Done!' )
1 I love Python
2 I love R
3 I love Matlab
4 I love C++
Done!
4慧脱、函數(shù)
Python 里函數(shù)太重要了 (說的好像在別的語言中函數(shù)不重要似的)渺绒。函數(shù)的通用好處就不用多說了吧,重復(fù)使用代碼,增強代碼可讀性等等宗兼。
還記得 Python 里面『萬物皆對象』么躏鱼?Python 把函數(shù)也當(dāng)成對象,可以從另一個函數(shù)中返回出來而去構(gòu)建高階函數(shù)殷绍,比如
- 參數(shù)是函數(shù)
- 返回值是函數(shù)
4.1 正規(guī)函數(shù)
Python 里面的正規(guī)函數(shù) (normal function) 就像其他語言的函數(shù)一樣染苛,之所以說正規(guī)函數(shù)是因為還有些「不正規(guī)」的,比如匿名函數(shù)主到,高階函數(shù)等等茶行。
但即便是正規(guī)函數(shù),Python 的函數(shù)具有非常靈活多樣的參數(shù)形態(tài)登钥,既可以實現(xiàn)簡單的調(diào)用畔师,又可以傳入非常復(fù)雜的參數(shù)。從簡到繁的參數(shù)形態(tài)如下:
位置參數(shù) (positional argument)
默認(rèn)參數(shù) (default argument) 默認(rèn)函數(shù)一定要放在位置參數(shù)后面牧牢,不然程序會報錯看锉。
可變參數(shù) (variable argument)
關(guān)鍵字參數(shù) (keyword argument)
命名關(guān)鍵字參數(shù) (name keyword argument)
參數(shù)組合
每種參數(shù)形態(tài)都有自己對應(yīng)的應(yīng)用,接下來用定義一個金融產(chǎn)品為例來說明各種參數(shù)形態(tài)的具體用法塔鳍。
4.1.1 位置參數(shù)和默認(rèn)參數(shù)
比較簡單伯铣,略過
4.1.2 可變參數(shù)
在 Python 函數(shù)中,還可以定義「可變參數(shù)」献幔。顧名思義懂傀,可變參數(shù)就是傳入的參數(shù)個數(shù)是可變的趾诗,可以是 0, 1, 2 到任意個蜡感。
金融產(chǎn)品未來多個折現(xiàn)現(xiàn)金流 (discounted cash flow, DCF),但不知道具體多少個恃泪,這時我們可以用 *args 來表示不確定個數(shù)的 DCF郑兴。下面程序也對 DCF 加總得到產(chǎn)品現(xiàn)值 (present value, PV)
def instrument4( id, ntl=1, curR='CNY', *args ):
PV = 0
for n in args:
PV = PV + n
print( 'id:', id )
print( 'notional:', ntl )
print( 'reporting currency:', curR )
print( 'present value:', PV*ntl )
如果一個產(chǎn)品 (單位本金) 在后 3 年的折現(xiàn)現(xiàn)金流為 1, 2, 3,將它們傳入 args贝乎,計算出它的現(xiàn)值為 600 = 100(1+2+3)情连。
instrument4( 'MM1001', 100, 'EUR', 1, 2, 3 )
--
id: MM1001
notional: 100
reporting currency: EUR
present value: 600
除了直接傳入多個參數(shù)之外,還可以將所有參數(shù)先組裝成元組 DCF览效,用以「*DCF」的形式傳入函數(shù) (DCF 是個元組却舀,前面加個通配符 * 是拆散元組,把元組的元素傳入函數(shù)中)
DCF = (1, 2, 3, 4, 5)
instrument4( 'MM1001', 10, 'EUR', *DCF )
--
id: MM1001
notional: 10
reporting currency: EUR
present value: 150
可變參數(shù)用兩種方式傳入
直接傳入锤灿,func(1, 2, 3)
先組裝列表或元組挽拔,再通過 args 傳入,func([1, 2, 3]) 或 func(*(1, 2, 3))
4.1.3 關(guān)鍵字參數(shù)
「可變參數(shù)」和「關(guān)鍵字參數(shù)」的同異總結(jié)如下:
- 可變參數(shù)允許傳入零個到任意個參數(shù)但校,它們在函數(shù)調(diào)用時自動組裝為一個元組 (tuple)
- 關(guān)鍵字參數(shù)允許傳入零個到任意個參數(shù)螃诅,它們在函數(shù)內(nèi)部自動組裝為一個字典 (dict)
在定義金融產(chǎn)品,有可能不斷增加新的信息,比如交易對手术裸、工作日慣例倘是、工作日計數(shù)慣例等等。我們可以用「關(guān)鍵字參數(shù)」來滿足這種需求袭艺,即用 **kw搀崭。
def instrument5( id, ntl=1, curR='CNY', *args, **kw ):
PV = 0
for n in args:
PV = PV + n
print( 'id:', id )
print( 'notional:', ntl )
print( 'reporting currency:', curR )
print( 'present value:', PV*ntl )
print( 'keyword:', kw)
如果不傳入任何「關(guān)鍵字參數(shù)」,kw 為空集猾编。
instrument5( 'MM1001', 100, 'EUR', 1, 2, 3 )
--
id: MM1001
notional: 100
reporting currency: EUR
present value: 600
keyword: {}
當(dāng)知道交易對手 (counterparty) 是高盛時门坷,給函數(shù)傳入一個「關(guān)鍵字參數(shù)」,ctp = 'GS'袍镀。
instrument5( 'MM1001', 100, 'EUR', 1, 2, 3, ctp='GS' )
--
id: MM1001
notional: 100
reporting currency: EUR
present value: 600
keyword: {'ctp': 'GS'}
當(dāng)知道日期計數(shù) (daycount) 是 act/365 時默蚌,再給函數(shù)傳入一個「關(guān)鍵字參數(shù)」,dc = 'act/365'苇羡。
instrument5( 'MM1001', 100, 'EUR', 1, 2, 3, dc='act/365', ctp='GS' )
---
id: MM1001
notional: 100
reporting currency: EUR
present value: 600
keyword: {'dc': 'act/365', 'ctp': 'GS'}
除了直接傳入多個參數(shù)之外绸吸,還可以將所有參數(shù)先組裝成字典 Conv,用以「**Conv」的形式傳入函數(shù) (Conv 是個字典设江,前面加個通配符 ** 是拆散字典锦茁,把字典的鍵值對傳入函數(shù)中)
DCF = (1, 2, 3, 4, 5)
Conv = {'dc':'act/365', 'bdc':'following'}
instrument5( 'MM1001', 10, 'EUR', *DCF, **Conv )
--
id: MM1001
notional: 10
reporting currency: EUR
present value: 150
keyword: {'dc': 'act/365', 'bdc': 'following'}
4.1.4 命名關(guān)鍵字參數(shù)
對于關(guān)鍵字參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的關(guān)鍵字參數(shù)叉存。
如果要限制關(guān)鍵字參數(shù)的名字码俩,就可以用「命名關(guān)鍵字參數(shù)」,例如歼捏,用戶希望交易對手 ctp 是個關(guān)鍵字參數(shù)稿存。這種方式定義的函數(shù)如下:
def instrument6( id, ntl=1, curR='CNY', *, ctp, **kw ):
print( 'id:', id )
print( 'notional:', ntl )
print( 'reporting currency:', curR )
print( 'counterparty:', ctp )
print( 'keyword:', kw)
從調(diào)用函數(shù) instrument6 得到的結(jié)果可看出 ctp 是「命名關(guān)鍵字參數(shù)」,而 dc 是「關(guān)鍵字參數(shù)」瞳秽。
instrument6( 'MM1001', 100, 'EUR', dc='act/365', ctp='GS' )
--
id: MM1001
notional: 100
reporting currency: EUR
counterparty: GS
keyword: {'dc': 'act/365'}
使用命名關(guān)鍵字參數(shù)時瓣履,要特別注意不能缺少參數(shù)名。下例沒有寫參數(shù)名 ctp练俐,因此 'GS' 被當(dāng)成「位置參數(shù)」袖迎,而原函數(shù)只有 3 個位置函數(shù),現(xiàn)在調(diào)用了 4 個腺晾,因此程序會報錯:
instrument6( 'MM1001', 100, 'EUR', 'GS', dc='act/365' )
--
TypeError: instrument6() takes from 1 to 3
positional arguments but 4 were given
4.1.5 參數(shù)組合
在 Python 中定義函數(shù)燕锥,可以用位置參數(shù)、默認(rèn)參數(shù)悯蝉、可變參數(shù)归形、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù),這 5 種參數(shù)中的 4 個都可以一起使用泉粉,但是注意连霉,參數(shù)定義的順序必須是:
- 位置參數(shù)榴芳、默認(rèn)參數(shù)、可變參數(shù)和關(guān)鍵字參數(shù)跺撼。
- 位置參數(shù)窟感、默認(rèn)參數(shù)、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)歉井。
要注意定義可變參數(shù)和關(guān)鍵字參數(shù)的語法:
*args 是可變參數(shù)柿祈,args 接收的是一個 tuple
**kw 是關(guān)鍵字參數(shù),kw 接收的是一個 dict
命名關(guān)鍵字參數(shù)是為了限制調(diào)用者可以傳入的參數(shù)名哩至,同時可以提供默認(rèn)值躏嚎。定義命名關(guān)鍵字參數(shù)不要忘了寫分隔符 *,否則定義的是位置參數(shù)菩貌。
4.2 匿名函數(shù)
在 Python 里有兩種函數(shù):
- 用 def 關(guān)鍵詞的正規(guī)函數(shù)
- 用 lambda 關(guān)鍵詞的匿名函數(shù)
匿名函數(shù) (anonymous function) 的說明如下:
func = lambda x, y: x*y #函數(shù)輸入是 x 和 y卢佣,輸出是它們的積 x*y
func(2, 3) --6
func = lambda *args: sum(args) #輸入是任意個數(shù)的參數(shù),輸出是它們的和
func( 1, 2, 3, 4, 5 ) --15
func = lambda **kwargs: 1 #輸入是任意鍵值對參數(shù)箭阶,輸出是 1
func( name='Steven', age='36' ) --1
正規(guī)函數(shù)vs匿名函數(shù)
lbd_sqr = lambda x: x ** 2
lbd_sqr --<function __main__.<lambda>(x)>
def sqr(x):
return x ** 2
sqr --<function __main__.sqr(x)>
print( sqr(9) ) --81
print( lbd_sqr(9) ) --81
4.3高階函數(shù)
高階函數(shù) (high-order function) 在函數(shù)化編程 (functional programming) 很常見虚茶,主要有兩種形式:
- 參數(shù)是函數(shù) (map, filter, reduce)
- 返回值是函數(shù) (closure, partial, currying)
4.3.1 Map, Filter, Reduce
Python 里面的 map, filter 和 reduce 屬于第一種高階函數(shù),參數(shù)是函數(shù)仇参。這時候是不是很自然的就想起了 lambda 函數(shù)嘹叫?
作為內(nèi)嵌在別的函數(shù)里的參數(shù),lambda 函數(shù)就像微信小程序一樣诈乒,即用即丟罩扇,非常輕便。
首先看看 map, filter 和 reduce 的語法:
map(函數(shù) f, 序列 x):對序列 x 中每個元素依次執(zhí)行函數(shù) f怕磨,將 f(x) 組成一個「map 對象」返回 (可以將其轉(zhuǎn)換成 list 或 set)
filter(函數(shù) f, 序列 x):對序列 x 中每個元素依次執(zhí)行函數(shù) f喂饥,將 f(x) 為 True 的結(jié)果組成一個「filter 對象」返回 (可以將其轉(zhuǎn)換成 list 或 set)
reduce(函數(shù) f, 序列 x):對序列 x 的第一個和第二個元素執(zhí)行函數(shù) f,得到的結(jié)果和序列 x 的下一個元素執(zhí)行函數(shù) f癌压,一直遍歷完的序列 x 所有元素仰泻。
lst = [1, 2, 3, 4, 5]
map_iter = map( lambda x: x**2, lst )
print( map_iter ) --<map object at 0x0000018C83E72390>
print( list(map_iter) ) --[1, 4, 9, 16, 25]
filter_iter = filter(lambda n: n % 2 == 1, lst)
print( filter_iter ) --<filter object at 0x0000018C83E722E8>
print( list(filter_iter) ) --[1, 3, 5]
from functools import reduce
reduce( lambda x,y: x+y, lst ) -- 15
reduce( lambda x,y: x+y, lst, 100 ) -- 115
注意 map_iter 是 map 函數(shù)的返回對象 (它是一個迭代器),想要將其內(nèi)容顯示出來滩届,需要用 list 將其轉(zhuǎn)換成「列表」形式。
小結(jié)一下被啼,對于 map, filter 和 reduce帜消,好消息是,Python 支持這些基本的操作浓体;而壞消息是泡挺,Python 不建議你使用它們。下節(jié)的「解析式」可以優(yōu)雅的替代 map 和 filter命浴。
4.3.2 閉包
Python 里面的閉包 (closure) 屬于第二種高階函數(shù)娄猫,返回值是函數(shù)贱除。下面是一個閉包函數(shù)。
def make_counter(init):
counter = [init]
def inc(): counter[0] += 1
def dec(): counter[0] -= 1
def get(): return counter[0]
def reset(): counter[0] = init
return inc, dec, get, reset
屬于第二類 (返回值是函數(shù)) 的高階函數(shù)還有「偏函數(shù)」和「柯里化」媳溺,由于它們比較特別月幌,因此專門分兩節(jié)來講解。
4.4 偏函數(shù)
偏函數(shù) (paritial function) 主要是把一個函數(shù)的參數(shù) (一個或多個) 固定下來悬蔽,用于專門的應(yīng)用上 (specialized application)扯躺。要用偏函數(shù)用從 functools 中導(dǎo)入 partial 包:
from functools import partial
舉個排序列表里元素的例子
lst = [3, 1, 2, 5, 4]
sorted( lst ) --[1, 2, 3, 4, 5]
我們知道 sort 函數(shù)默認(rèn)是按升序排列,假設(shè)在你的應(yīng)用中是按降序排列蝎困,你可以把函數(shù)里的 reverse 參數(shù)設(shè)置為 True录语。
sorted( lst, reverse=True ) --[5, 4, 3, 2, 1]
這樣每次設(shè)定參數(shù)很麻煩,你可以專門為「降序排列」的應(yīng)用定義一個函數(shù)禾乘,比如叫 sorted_dec澎埠,用偏函數(shù) partial 把內(nèi)置的 sort 函數(shù)里的 reverse 固定住,代碼如下:
sorted_dec = partial( sorted, reverse=True )
sorted_dec --functools.partial(<built-in function sorted>, reverse=True)
不難發(fā)現(xiàn) sorted_dec 是一個函數(shù)始藕,而且參數(shù)設(shè)置符合我們的應(yīng)用失暂,把該函數(shù)用到列表就能對于降序排列。
sorted_dec( lst ) --[5, 4, 3, 2, 1]
小結(jié)鳄虱,當(dāng)函數(shù)的參數(shù)個數(shù)太多弟塞,需要簡化時,使用 functools.partial 可以創(chuàng)建一個新的函數(shù)拙已,即偏函數(shù)决记,它可以固定住原函數(shù)的部分參數(shù),從而在調(diào)用時更簡單倍踪。
4.5 柯里化
最簡單的柯里化 (currying) 指的是將原來接收 2 個參數(shù)的函數(shù) f(x, y) 變成新的接收 1 個參數(shù)的函數(shù) g(x) 的過程系宫,其中新函數(shù) g = f(y)。
以普通的加法函數(shù)為例:
#參數(shù)是 x 和 y建车,輸出 x + y
def add1(x, y):
return x + y
# 通過嵌套函數(shù)可以把函數(shù) add1 轉(zhuǎn)換成柯里化函數(shù) add2扩借。
# 參數(shù)是 x,輸出 x + y
def add2(x):
def add(y):
return x + y
return add
#參數(shù)是 y缤至,輸出 2 + y
g = add2(2)
print( add1(2, 3) ) --5
print( add2(2)(3) ) --5
print( g(3) ) --5
比較「普通函數(shù) add1」和「柯里化函數(shù) add2」的調(diào)用潮罪,結(jié)果都一樣。
5 解析式
解析式 (comprehension) 是將一個可迭代對象轉(zhuǎn)換成另一個可迭代對象的工具领斥。
第一個可迭代對象:可以是任何容器類型數(shù)據(jù)嫉到。
第二個可迭代對象:
- 列表解析式:可迭代對象是 list
- 字典解析式:可迭代對象是 dict
- 集合解析式:可迭代對象是 set
5.1 列表解析式
#從一個含整數(shù)列表中把奇數(shù) (odd number) 挑出來
lst = [1, 2, 3, 4, 5]
odds = []
for n in lst:
if n % 2 == 1:
odds.append(n )
odds --[1, 3, 5]
#任務(wù)完成了,但這個代碼有好幾行呢月洛,不簡潔何恶,看看下面這一行代碼:
odds = [n for n in lst if n % 2 == 1]
odds --[1, 3, 5]
你可以把「for 循環(huán)」到「解析式」的過程想像成一個「復(fù)制-粘貼」的過程:
- 將「for 循環(huán)」的新列表復(fù)制到「解析式」里
- 將 append 里面的表達(dá)式 n 復(fù)制到新列表里
- 復(fù)制循環(huán)語句 for n in lst 到新列表里,不要最后的冒號
-
復(fù)制條件語句 if n%2 == 1 到新列表里嚼黔,不要最后的冒號
#用「列表解析式」將一個二維列表中的元素按行一個個展平
# for循環(huán)
flattened = []
for row in lst:
for n in row:
flattened.append(n)
# 解析式:
flattened = [n for row in lst for n in row]
再回顧下三種解析式细层,我們發(fā)現(xiàn)其實它們都可以實現(xiàn)上節(jié)提到的 filter 和 map 函數(shù)的功能惜辑,用專業(yè)計算機的語言說,解析式可以看成是 filter 和 map 函數(shù)的語法糖疫赎。
# 列表解析式
[ n*2 for n in lst if n%2 == 1]
# map/filter
list( map(lambda n: n*2, filter(lambda n: n%2 == 1, lst)) )
5.2 例子
# 用解析式將二維元組里每個元素提取出來并存儲到一個列表中盛撑。
tup = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
flattened = [x for t in tup for x in t]
flattened --[1, 2, 3, 4, 5, 6, 7, 8, 9]
#把上面「二維元組」轉(zhuǎn)換成「二維列表」
[ [x for x in t] for t in tup ] --[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 用解析式把以下這個不規(guī)則的列表 a 打平 (flatten)
# 正規(guī)函數(shù)
a = [1, 2, [3, 4], [[5, 6], [7, 8]]]
def f(x):
if type(x) is list:
return [y for l in x for y in f(l)]
else:
return [x]
f(a) --[1, 2, 3, 4, 5, 6, 7, 8]
a = [1, 2, [3, 4], [[5, 6], [7, 8]]]
f = lambda x: [y for l in x for y in f(l)]
if type(y) is list else [x]
f(a) --[1, 2, 3, 4, 5, 6, 7, 8]
函數(shù) f(x) 是一個遞推函數(shù),當(dāng) x 是元素虚缎,返回 [x], 那么
f(1) 的返回值是 [1]
f(2) 的返回值是 [2]
當(dāng) x 是列表撵彻,返回 [y for l in x for y in f(l)],當(dāng) x = [3 ,4] 時
for l in x:指的是 x 里每個元素 l实牡,那么 l 遍歷 3 和 4
for y in f(l):指的是 f(l) 里每個元素 y
當(dāng) l = 3陌僵,是個元素,那么 f(l) = [3], y 遍歷 3
當(dāng) l = 4创坞,是個元素碗短,那么 f(l) = [4], y 遍歷 4
總結(jié)
數(shù)據(jù)類型分兩種:
單獨類型:整型、浮點型题涨、布爾型
容器類型:字符偎谁、元組、列表纲堵、字典巡雨、集合
條件語句 (if, if-else, if-elif-else, nested if) 是為了在不同條件下執(zhí)行不同操作,而迭代循環(huán) (while, for) 是重復(fù)的完成相同操作席函。
函數(shù)包括正規(guī)函數(shù) (用 def) 和匿名函數(shù) (用 lambda)铐望,函數(shù)的參數(shù)形態(tài)也多種多樣,有位置參數(shù)茂附、默認(rèn)參數(shù)正蛙、可變參數(shù)、關(guān)鍵字參數(shù)营曼、命名關(guān)鍵字參數(shù)乒验。匿名函數(shù)主要用在高階函數(shù)中,高階函數(shù)的參數(shù)可以是函數(shù) (Python 里面內(nèi)置 map/filter/reduce 函數(shù))蒂阱,返回值也可以是參數(shù) (閉包锻全、偏函數(shù)、柯里化函數(shù))蒜危。
解析式并沒有解決新的問題虱痕,只是以一種更加簡潔,可讀性更高的方式解決老的問題辐赞。解析式可以把「帶 if 條件的 for 循環(huán)」用一行程序表達(dá)出來,也可以實現(xiàn) map 加 filter 的功能硝训。
按照 Python 里「萬物皆對象」的思路响委,學(xué)習(xí)每一個對象里面的屬性 (attributes) 和方法 (methods)新思,你不需要記住所有,有個大概印象有哪些赘风,通過 dir() 來鎖定具體表達(dá)式夹囚,再去官網(wǎng)上查詢所有細(xì)節(jié)。這么學(xué)真的很系統(tǒng)而簡單邀窃。此外學(xué)的時候一定要帶著“它的優(yōu)缺點是什么”這樣的問題荸哟,所有東西都有 trade-off,一個滿身都是缺點的東西就沒有存在的必要瞬捕,既然存在肯定有可取之處鞍历。