FluentPython 元組不僅僅是不可變的列表
元組
元組其實(shí)是對數(shù)據(jù)的記錄:元組中的每個元素都存放了記錄中一個字段的數(shù)據(jù),外加這個字段的位置。正是這個位置信息給數(shù)據(jù)賦予了意義。
如果只把元組理解為不可變的列表,那其他信息——它所含有的元素的總數(shù)和它們的位置——似乎就變得可有可無。但是如果把元組當(dāng)作一些字段的集合,那么數(shù)量和位置信息就變得非常重要了。
>>> lax_coordinates = (33.9425, -118.408056)
>>> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
>>> traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'),('ESP', 'XDA205856')]
>>> for passport in sorted(traveler_ids):
... print('%s/%s' % passport)
...
BRA/CE342567
ESP/XDA205856
USA/31195855
>>> for country, _ in traveler_ids: #注意下劃線的功能,看下節(jié)拆包
... print(country)
USA
BRA
ESP
元組拆包
上面示例中,我們把元組 ('Tokyo', 2003, 32450, 0.66, 8014) 里的元素分別賦值給變量 city、year、pop、chg 和 area,而這所有的賦值我們只用一行聲明就寫完了。同樣,在后面一行中,一個 % 運(yùn)算符就把 passport 元組里的元素對應(yīng)到了 print 函數(shù)的格式字符串空檔中。這兩個都是對元組拆包的應(yīng)用。
元組拆包用法_os.path.split()
>>> import os
>>> _, filename = os.path.split('/home/qfyu/.ssh/idrsa.pub') #注意“_”的用法
>>> filename
'idrsa.pub'
>>>
在進(jìn)行拆包的時候,我們不總是對元組里所有的數(shù)據(jù)都感興趣,_ 占位符能幫助處理這種情況
在元組拆包中使用 * 也可以幫助我們把注意力集中在元組的部分元素上。用*來處理剩下的元素在 python 中,函數(shù)用 *args 來獲取不確定數(shù)量的參數(shù)算是一種經(jīng)典寫法了
舉例說明;
>>> a,b,*rest = range(5)
>>> a,b,rest
(0, 1, [2, 3, 4]) # 剩下的元素存在列表中
>>> a,b,*rest = range(3)
>>> a,b,rest
(0, 1, [2])
>>> a,b,*rest = range(2)
>>> a,b,rest
(0, 1, [])
>>>
在平行賦值中,* 前綴只能用在一個變量名前面,但是這個變量可以出現(xiàn)在賦值表達(dá)式的任意位置:
>>> a, *body, c, d = range(5)
>>> a, body, c, d
(0, [1, 2], 3, 4)
>>> *head, b, c, d = range(5)
>>> head, b, c, d
([0, 1], 2, 3, 4)
套件元組拆包
嵌套元組:接受表達(dá)式的元組可以是嵌套式的,例如 (a, b, (c, d))
metro_areas = [
('Tokyo','JP',36.933,(35.689722,139.691667)), # ?每個元組內(nèi)有 4 個元素,其中最后一個元素是一對坐標(biāo)。
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
]
print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.'))
fmt = '{:15} | {:9.4f} | {:9.4f}'
for name, cc, pop, (latitude, longitude) in metro_areas: # ? 我們把輸入元組的最后一個元素拆包到由變量構(gòu)成的元組里,這樣就獲取了坐標(biāo)。
if longitude <= 0:
print(fmt.format(name, latitude, longitude))
上面示例的輸出是這樣的:
| lat. | long.
Mexico City | 19.4333 | -99.1333
New York-Newark | 40.8086 | -74.0204
Sao Paul | -23.5478 | -46.6358
具名元組 namedtuple
collections.namedtuple 是一個工廠函數(shù),它可以用來構(gòu)建一個帶字段名的元組和一個有名字的類——這個帶名字的類對調(diào)試程序有很大幫助。
這樣新建 Card 類的:
Card = collections.namedtuple('Card', ['rank', 'suit'])
? 創(chuàng)建一個具名元組需要兩個參數(shù),一個是類名,另一個是類的各個字段的名字。后者可以是由數(shù)個字符串組成的可迭代對象,或者是由空格分隔開的字段名組成的字符串。
? 存放在對應(yīng)字段里的數(shù)據(jù)要以一串參數(shù)的形式傳入到構(gòu)造函數(shù)中(注意,元組的構(gòu)造函數(shù)卻只接受單一的可迭代對象)。
? 你可以通過字段名或者位置來獲取一個字段的信息
列表或元組的方法或?qū)傩?/h2>
列表 元組
s.__add__(s2) ● ● s + s2,拼接
s.__iadd__(s2) ● s += s2,就地拼接
s.append(e) ● 在尾部添加一個新元素
s.clear() ● 刪除所有元素
s.__contains__(e) ● ● s 是否包含 e
s.copy() ● 列表的淺復(fù)制
s.count(e) ● ● e 在 s 中出現(xiàn)的次數(shù)
s.__delitem__(p) ● 把位于 p 的元素刪除
s.extend(it) ● 把可迭代對象 it 追加給 s
s.__getitem__(p) ● ● s[p],獲取位置 p 的元素
s.__getnewargs__() ● 在 pickle 中支持更加優(yōu)化的序列化
s.index(e) ● ● 在 s 中找到元素 e 第一次出現(xiàn)的位置
s.insert(p,e) ● 在位置 p 之前插入元素e
s.__iter__() ● ● 獲取 s 的迭代器
s.__len__() ● ● len(s),元素的數(shù)量
s.__mul__(n) ● ● s * n,n 個 s 的重復(fù)拼接
s.__imul__(n) ● s *= n,就地重復(fù)拼接
s.__rmul__(n) ● ● n * s,反向拼接 *
s.pop([p]) ● 刪除最后或者是(可選的)位于 p 的元素,并返回它的值
s.remove(e) ● 刪除 s 中的第一次出現(xiàn)的 e
s.reverse() ● 就地把 s 的元素倒序排列
s.__reversed__() ● 返回 s 的倒序迭代器
s.__setitem__(p,e) ● s[p] = e,把元素 e 放在位置p,替代已經(jīng)在那個位置的元素
s.sort([key],[reverse]) ● 就地對 s 中的元素進(jìn)行排序,可選的參數(shù)有鍵(key)和是否倒序(reverse)
列表 元組
s.__add__(s2) ● ● s + s2,拼接
s.__iadd__(s2) ● s += s2,就地拼接
s.append(e) ● 在尾部添加一個新元素
s.clear() ● 刪除所有元素
s.__contains__(e) ● ● s 是否包含 e
s.copy() ● 列表的淺復(fù)制
s.count(e) ● ● e 在 s 中出現(xiàn)的次數(shù)
s.__delitem__(p) ● 把位于 p 的元素刪除
s.extend(it) ● 把可迭代對象 it 追加給 s
s.__getitem__(p) ● ● s[p],獲取位置 p 的元素
s.__getnewargs__() ● 在 pickle 中支持更加優(yōu)化的序列化
s.index(e) ● ● 在 s 中找到元素 e 第一次出現(xiàn)的位置
s.insert(p,e) ● 在位置 p 之前插入元素e
s.__iter__() ● ● 獲取 s 的迭代器
s.__len__() ● ● len(s),元素的數(shù)量
s.__mul__(n) ● ● s * n,n 個 s 的重復(fù)拼接
s.__imul__(n) ● s *= n,就地重復(fù)拼接
s.__rmul__(n) ● ● n * s,反向拼接 *
s.pop([p]) ● 刪除最后或者是(可選的)位于 p 的元素,并返回它的值
s.remove(e) ● 刪除 s 中的第一次出現(xiàn)的 e
s.reverse() ● 就地把 s 的元素倒序排列
s.__reversed__() ● 返回 s 的倒序迭代器
s.__setitem__(p,e) ● s[p] = e,把元素 e 放在位置p,替代已經(jīng)在那個位置的元素
s.sort([key],[reverse]) ● 就地對 s 中的元素進(jìn)行排序,可選的參數(shù)有鍵(key)和是否倒序(reverse)