3.1 數(shù)據(jù)結(jié)構(gòu)和序列
元組
元組是一個固定長度辨赐,不可改變的Python序列對象优俘。圓括號。
用tuple可以將任意序列或迭代器轉(zhuǎn)換成元組:
可以用方括號訪問元組中的元素掀序。序列是從0開始的:
元組中存儲的對象可能是可變對象帆焕。一旦創(chuàng)建了元組,元組中的對象就不能修改了:
tuple方法
因為元組的大小和內(nèi)容不能修改森枪,count方法(也適用于列表)可以統(tǒng)計某個值得出現(xiàn)頻率:
In [34]: a = (1, 2, 2, 2, 3, 4, 2)
In [35]: a.count(2)
Out[35]: 4
列表
與元組對比视搏,列表的長度可變、內(nèi)容可以被修改县袱。你可以用方括號定義浑娜,或用list函數(shù)
list函數(shù)常用來在數(shù)據(jù)處理中實體化迭代器或生成器:
用append在列表末尾添加元素:b_list.append('dwarf')
insert可以在特定的位置插入元素:b_list.insert(1, 'red')
插入的序號必須在0和列表長度之間。
insert的逆運算是pop式散,它移除并返回指定位置的元素:b_list.pop(2)
用remove去除某個值筋遭,remove會先尋找第一個值并除去:
用in可以檢查列表是否包含某個值:'dwarf' in b_list
否定in可以再加一個not:'dwarf' not in b_list
在列表中檢查是否存在某個值遠比字典和集合速度慢
串聯(lián)和組合列表
與元組類似,可以用加號將兩個列表串聯(lián)起來:[4, None, 'foo'] + [7, 8, (2, 3)]
用extend方法可以追加多個元素: x.extend([7, 8, (2, 3)])
通過加法將列表串聯(lián)的計算量較大,因為要新建一個列表漓滔,并且要復(fù)制對象编饺。用extend追加元素比串聯(lián)方法快。
排序
用sort函數(shù)將一個列表原地排序(不創(chuàng)建新的對象): a.sort()對數(shù)字
sort的二級排序key很好用响驴,例如透且,我們可以按長度對字符串進行排序:b.sort(key=len)
二分搜索和維護已排序的列表
bisect模塊支持二分查找,和向已排序的列表插入值豁鲤。
bisect.bisect可以找到插入值后仍保證排序的位置秽誊,bisect.insort是向這個位置插入值: bisect.bisect(c, 2),bisect.insort(c, 6)
注意:bisect模塊不會檢查列表是否已排好序琳骡,進行檢查的話會耗費大量計算锅论。因此,對未排序的列表使用bisect不會產(chǎn)生錯誤楣号,但結(jié)果不一定正確最易。
切片
用切邊可以選取大多數(shù)序列類型的一部分,切片的基本形式是在方括號中使用start:stop:step
在第二個冒號后面使用的step炫狱,指隔step取一個元素:seq[::2]
step=-1可以將列表或元組顛倒過來:seq[::-1]
序列函數(shù)
enumerate函數(shù)可以返回(i, value)元組序列來跟蹤當前項的序號:for i, value in enumerate(collection):
sorted函數(shù)可以從任意序列的元素返回一個新的排好序的列表:sorted([7, 1, 2, 6, 0, 3, 2])藻懒。sorted函數(shù)可以接受和sort相同的參數(shù)。
zip可以將多個列表毕荐、元組或其它序列成對組合成一個元組列表:zipped = zip(seq1, seq2)
zip可以處理任意多的序列束析,元素的個數(shù)取決于最短的序列:
zip的常見用法之一是同時迭代多個序列,可能結(jié)合enumerate使用:for i, (a, b) in enumerate(zip(seq1, seq2)):
給出一個“被壓縮的”序列憎亚,zip可以被用來解壓序列员寇。也可以當作把行的列表轉(zhuǎn)換為列的列表:first_names, last_names = zip(*pitchers)
reversed函數(shù)可以從后向前迭代一個序列:list(reversed(range(10)))
字典
更為常見的名字是哈希映射或關(guān)聯(lián)數(shù)組。第美。它是鍵值對的大小可變集合蝶锋,鍵和值都是Python對象。創(chuàng)建方法:尖括號什往,用冒號分隔鍵和值: empty_dict = {}扳缕,d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}
像訪問列表或元組中的元素一樣,訪問别威、插入或設(shè)定字典中的元素:d1[7] = 'an integer'躯舔,d1['b']
用檢查列表和元組是否包含某個值得方法,檢查字典中是否包含某個鍵:'b' in d1
用del關(guān)鍵字或pop方法(返回值得同時刪除鍵)刪除值:
keys和values是字典的鍵和值的迭代器方法省古。雖然鍵值對沒有順序粥庄,這兩個方法可以用相同的順序輸出鍵和值:
In [117]: list(d1.keys())
Out[117]: ['a', 'b', 7]
In [118]: list(d1.values())
Out[118]: ['some value', [1, 2, 3, 4], 'an integer']
用update方法可以將一個字典與另一個融合:d1.update({'b' : 'foo', 'c' : 12})
update方法是原地改變字典,因此任何傳遞給update的鍵的舊的值都會被舍棄豺妓。
默認值
dict的方法get和pop可以取默認值進行返回:value = some_dict.get(key, default_value)
get默認會返回None惜互,如果不存在鍵布讹,pop會拋出一個例外。
setdefault方法:
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
有效的鍵類型
字典的值可以是任意Python對象训堆,而鍵通常是不可變的標量類型(整數(shù)描验、浮點型、字符串)或元組(元組中的對象必須是不可變的)坑鱼。這被稱為“可哈希性”膘流。可以用hash函數(shù)檢測一個對象是否是可哈希的(可被用作字典的鍵):hash('string')
要用列表當做鍵姑躲,一種方法是將列表轉(zhuǎn)化為元組睡扬,只要內(nèi)部元素可以被哈希,它也就可以被哈希: d[tuple([1, 2, 3])] = 5
集合
集合是無序的不可重復(fù)的元素的集合黍析。你可以把它當做字典,但是只有鍵沒有值屎开〔妫可以用兩種方式創(chuàng)建集合:通過set函數(shù)或使用尖括號set語句:
In [133]: set([2, 2, 2, 1, 3, 3])
Out[133]: {1, 2, 3}
In [134]: {2, 2, 2, 1, 3, 3}
Out[134]: {1, 2, 3}
用union方法或者|運算符可以取兩個集合中不重復(fù)的元素: a.union(b) ,a | b
與字典類似奄抽,集合元素通常都是不可變的蔼两。要獲得類似列表的元素,必須轉(zhuǎn)換成元組: my_set = {tuple(my_data)}
你還可以檢測一個集合是否是另一個集合的子集或父集:{1, 2, 3}.issubset(a_set)
集合的內(nèi)容相同時逞度,集合才對等额划,因為是無序的所以順序可以不同:
列表、集合和字典推導(dǎo)式
列表推導(dǎo)式允許用戶方便的從一個集合過濾元素档泽,形成列表俊戳,在傳遞參數(shù)的過程中還可以修改元素。形式如下:
[expr for val in collection if condition]
等同于下面的for循環(huán);
result = []
for val in collection:
if condition:
result.append(expr)
給定一個字符串列表馆匿,我們可以過濾出長度在2及以下的字符串抑胎,并將其轉(zhuǎn)換成大寫:
In [154]: strings = ['a', 'as', 'bat', 'car', 'dove', 'python'] In [155]: [x.upper() for x in strings if len(x) > 2] Out[155]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
字典的推導(dǎo)式如下所示:dict_comp = {key-expr : value-expr for value in collection if condition}
集合的推導(dǎo)式用的是尖括號:set_comp = {expr for value in collection if condition}
假如我們只想要字符串的長度,用集合推導(dǎo)式的方法非常方便:
In [156]: unique_lengths = {len(x) for x in strings}
In [157]: unique_lengths
Out[157]: {1, 2, 3, 4, 6}
用map函數(shù)可以進一步簡化:set(map(len, strings))
我們可以創(chuàng)建一個字符串的查找映射表以確定它在列表中的位置:
loc_mapping = {val : index for index, val in enumerate(strings)}
3.2 函數(shù)
函數(shù)使用def關(guān)鍵字聲明渐北,用return關(guān)鍵字返回值:
關(guān)鍵字參數(shù)通常用于指定默認值或可選參數(shù)阿逃。關(guān)鍵字參數(shù)必須位于位置參數(shù)(如果有的話)之后。你可以任何順序指定關(guān)鍵字參數(shù)赃蛛。
命名空間恃锉、作用域,和局部函數(shù)
任何在函數(shù)中賦值的變量默認都是被分配到局部命名空間(local namespace)中的呕臂。局部命名空間是在函數(shù)被調(diào)用時創(chuàng)建的破托,函數(shù)參數(shù)會立即填入該命名空間。在函數(shù)執(zhí)行完畢之后诵闭,局部命名空間就會被銷毀
可以在函數(shù)中對全局變量進行賦值操作炼团,但是那些變量必須用global關(guān)鍵字聲明成全局的才行:
注意:我常常建議人們不要頻繁使用global關(guān)鍵字澎嚣。因為全局變量一般是用于存放系統(tǒng)的某些狀態(tài)的。如果你發(fā)現(xiàn)自己用了很多瘟芝,那可能就說明得要來點兒面向?qū)ο缶幊塘耍词褂妙悾?/p>
返回多個值
return a, b, c
return {'a' : a, 'b' : b, 'c' : c}
生成器
能以一種一致的方式對序列進行迭代(比如列表中的對象或文件中的行)是Python的一個重要特點易桃。這是通過一種叫做迭代器協(xié)議(iterator protocol,它是一種使對象可迭代的通用方式)的方式實現(xiàn)的锌俱,一個原生的使對象可迭代的方法晤郑。比如說,對字典進行迭代可以得到其所有的鍵:
In [180]: some_dict = {'a': 1, 'b': 2, 'c': 3}
In [181]: for key in some_dict:
.....: print(key)
a
b
c
當你編寫for key in some_dict時贸宏,Python解釋器首先會嘗試從some_dict創(chuàng)建一個迭代器:
In [182]: dict_iterator = iter(some_dict)
In [183]: dict_iterator
Out[183]: <dict_keyiterator at 0x7fbbd5a9f908>
作者:SeanCheney
鏈接:http://www.reibang.com/p/b444cda10aa0
來源:簡書
著作權(quán)歸作者所有造寝。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處吭练。