集合是一種很有用的數學操作,比如列表去重,或是理清兩組數據之間的關系,集合的操作符和位操作符有交集,注意不要弄混:
A = set([1, 2, 3, 4])
B = {3, 4, 5, 6}
C = set([1, 1, 2, 2, 2, 3, 3, 3, 3])
print(C) # 集合的去重效果,set([1, 2, 3])
print(A | B) # 求并集,set([1, 2, 3, 4, 5, 6])
print(A & B) # 求交集,set([3, 4])
print(A - B) # 求差集,屬于A但不屬于B的,set([1, 2])
print(B - A) # 求差集,屬于B但不屬于A的,set([5, 6])
print(A ^ B) # 求對稱差集,相當于(A-B)|(B-A),set([1, 2, 5, 6])
字典
字典是一種非常常見的“鍵-值”(key-value)映射結構,鍵無重復,一個鍵不能對應多個值,不過多個鍵可以指向一個值。還是通過例子來了解,構建一個名字->年齡的字典,并執行一些常見操作:
a = {'Tom': 8, 'Jerry': 7}
print(a['Tom']) # 8
b = dict(Tom=8, Jerry=7) # 一種字符串作為鍵更方便的初始化方式
print(b['Tom']) # 8
if 'Jerry' in a: # 判斷'Jerry'是否在keys里面
print(a['Jerry']) # 7
print(a.get('Spike')) # None,通過get獲得值,即使鍵不存在也不會報異常
a['Spike'] = 10
a['Tyke'] = 3
a.update({'Tuffy': 2, 'Mammy Two Shoes': 42})
print(a.values()) # dict_values([8, 2, 3, 7, 10, 42])
print(a.pop('Mammy Two Shoes')) # 移除'Mammy Two Shoes'的鍵值對,并返回42
print(a.keys()) # dict_keys(['Tom', 'Tuffy', 'Tyke', 'Jerry', 'Spike'])
注意到初始化字典和集合很像,的確如此,集合就像是沒有值只有鍵的字典。既然有了人名到年齡的映射,也許你立馬想到是否可以給字典排序?在Python3.6之前,這個問題是錯誤的,字典是一種映射關系,沒有順序。當然了,如果要把(鍵, 值)的這種對進行排序,是沒有問題的,前提是先把字典轉化成可排序的結構,items()或者iteritems()可以做到這件事,接上段代碼繼續:
b = a.items()
print(b) # [('Tuffy', 2), ('Spike', 10), ('Tom', 8), ('Tyke', 3), ('Jerry', 7)]
from operator import itemgetter
c = sorted(a.items(), key=itemgetter(1))
print(c) # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]
d = sorted(a.iteritems(), key=itemgetter(1))
print(d) # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]
e = sorted(a)
print(e) # 只對鍵排序,['Jerry', 'Spike', 'Tom', 'Tuffy', 'Tyke']
items()可以把字典中的鍵值對轉化成一個列表,其中每個元素是一個tuple,tuple的第一個元素是鍵,第二個元素是值。變量c是按照值排序,所以需要一個操作符itemgetter,去位置為1的元素作為排序參考,如果直接對字典排序,則其實相當于只是對鍵排序。字典被當作一個普通的可遍歷結構使用時,都相當于遍歷字典的鍵。如果覺得字典沒有順序不方便,可以考慮使用OrderedDict,使用方式如下:
from collections import OrderedDict
a = {1: 2, 3: 4, 5: 6, 7: 8, 9: 10}
b = OrderedDict({1: 2, 3: 4, 5: 6, 7: 8, 9: 10})
print(a) # {1: 2, 3: 4, 9: 10, 5: 6, 7: 8}
print(b) # OrderedDict([(1, 2), (3, 4), (9, 10), (5, 6), (7, 8)])
這樣初始化時的順序就保留了,除了有序的特性以外,用法上和字典沒有區別。2016年9月,Guido宣布在Python3.6中,字典將默認有序,這樣就不用糾結了。另外需要注意的一點是字典是通過哈希表實現的,所以鍵必須是可哈希的, list不能被哈希,所以也不能作為字典的鍵,而tuple就可以。
因為上上段代碼中用到了iteritems(),所以這里順帶提一下迭代器(iterator),迭代器相當于一個函數,每次調用都返回下一個元素,從遍歷的角度來看就和列表沒有區別了。iteritems()就是一個迭代器,所以效果一樣,區別是迭代器占用更少內存,因為不需要一上來就生成整個列表。一般來說,如果只需要遍歷一次,用迭代器是更好的選擇,若是要多次頻繁從一個可遍歷結構中取值,且內存夠,則直接生成整個列表會更好。當然,用迭代器生成一個完整列表并不麻煩,所以有個趨勢是把迭代器作為默認的可遍歷方式,比如前面我們使用過用來生成等差數列列表的range(),在Python2中對應的迭代器形式是xrange()。在Python3中,range()就不再產生一個列表了,而是作為迭代器,xrange()直接沒了。
分支和循環
從這節開始,代碼就未必適合在Python終端中輸入了,選個順手的編輯器或者IDE。作者良心推薦PyCharm,雖然慢,但好用,社區版免費:
PyCharm
for循環
評論
查看更多