python3-cookbook中每個小節以問題、解決方案和討論三個部分探討了Python3在某類問題中的最優解決方式,或者說是探討Python3本身的資料結構、函式、類等特性在某類問題上如何更好地使用,這本書對于加深Python3的理解和提升Python編程能力的都有顯著幫助,特別是對怎么提高Python程式的性能會有很好的幫助,如果有時間的話強烈建議看一下,
本文為學習筆記,文中的內容只是根據自己的作業需要和平時使用寫了書中的部分內容,并且文中的示例代碼大多直接貼的原文代碼,當然,代碼多數都在Python3.6的環境上都驗證過了的,不同領域的編程關注點也會有所不同,有興趣的可以去看全文,
python3-cookbook:https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
1.2 解壓可迭代物件賦值給多個變數
此小節主要是對于星號運算式的探討,當想要將一個可迭代物件的部分元素賦值給某個變數,尤其是這部分元素的數量并不確定時,星號運算式就能很好的排上用場了,
使用場景1:普通的分割符,需要注意的是,星號運算式的變數為串列型別,即使該變數中的元素為0個,
>>> record = ('Dave', '[email protected]', '773-555-1212', '847-555-1212') >>> name, email, *phone_numbers = record >>> name 'Dave' >>> email '[email protected]' >>> phone_numbers ['773-555-1212', '847-555-1212'] >>> name, email, phone_number1, phone_number2, *others = record >>> others [] >>>
使用場景2:在迭代元素為可變長序列時,星號運算式也很好用,
records = [ ('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4), ] def do_foo(x, y): print('foo', x, y) def do_bar(s): print('bar', s) for tag, *args in records: if tag == 'foo': do_foo(*args) elif tag == 'bar': do_bar(*args)
1.3 保留最后 N 個元素
在迭代操作或者其他操作中,如果想要保留一個有固定元素個數的物件的時候,可以考慮使用collections.deque,它會構造一個固定長度的佇列(如果指定了的話),當佇列滿了之后,如果繼續往佇列中添加元素,就會洗掉最老的元素,再添加新的元素進去,deque也有對應的方法在佇列的兩端添加和彈出元素,雖然可以使用串列等方法實作相同的功能,但deque的性能上是優于串列的插入洗掉等操作的,當然,具體的場景還是要看個人的使用習慣和選擇了,此小節只是給出了另一個值得考慮的解決方案,
>>> from collections import deque >>> q = deque(maxlen=3) >>> q.append(1) >>> q.append(2) >>> q.append(3) >>> q deque([1, 2, 3], maxlen=3) >>> q.append(4) >>> q deque([2, 3, 4], maxlen=3) >>> q.appendleft(5) >>> q deque([5, 2, 3], maxlen=3) >>> q.pop() 3 >>> q deque([5, 2], maxlen=3) >>> q.popleft() 5 >>> q deque([2], maxlen=3) >>>
1.4 查找最大或最小的 N 個元素
在一個元素個數比較多的集合中查找最大或最小的N個元素,并且要查找的元素個數相對于集合本身元素個數較小時,可以考慮使用heapq模塊中的nlargest和nsmallest函式,需要注意的是如果要查找的元素個數和集合本身的元素個數相近的話,建議使用先排序后切割的方式,如sorted(items)[:N],
在heapq中,由于它是堆結構的,所以第一個元素永遠是最小的,當你想要多次使用集合,并且每次使用集合時可以得到集合的最小元素時,可以考慮使用heapq模塊,當然,如果你僅僅是想要得到該集合中的唯一一個最大或最小的元素時,建議直接使用max或min函式,
>>> import heapq >>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] >>> heapq.nlargest(3, nums) [42, 37, 23] >>> heapq.nsmallest(3, nums) [-4, 1, 2] >>> portfolio = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'ACME', 'shares': 75, 'price': 115.65} ] >>> heapq.nlargest(3, portfolio, key=lambda s: s['price']) [{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}] >>> >>> heap = list(nums) >>> heapq.heapify(heap) # 將資料進行堆排序后放入串列中 >>> heap [-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8] >>> heapq.heappop(heap) -4 >>> heapq.heappop(heap) 1 >>> heapq.heappop(heap) 2 >>>
1.8 字典的運算
如果想要某個字典中鍵最大(最小)或值最大(最小)的鍵值對,可以使用zip()函式將鍵值先反轉過來,
>>> prices = { 'ACME': 45.23, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.20, 'FB': 10.75 } >>> max(zip(prices.values(), prices.keys())) (612.78, 'AAPL') >>> min(zip(prices.values(), prices.keys())) (10.75, 'FB') >>>
1.11 命名切片
程式中使用下標進行切片的情況還是比較多的,如果下標在使用時寫死的話,就會使得程式后期變得難以維護,這時可以考慮將切片的下標換為內置的slice函式,所有的下標切片都可以使用這個函式,
>>> items = [0, 1, 2, 3, 4, 5, 6] >>> a = slice(2, 4) >>> items[2:4] [2, 3] >>> items[a] [2, 3] >>> items[a] = [10, 11] >>> items [0, 1, 10, 11, 4, 5, 6] >>> a.start 2 >>> a.stop 4 >>> a.step >>> >>> record = '....................100 .......513.25 ..........' >>> cost = int(record[20:23]) * float(record[31:37]) # 下標切片寫死在代碼里,不建議這樣做 >>> cost 51325.0 >>> SHARES = slice(20, 23) >>> PRICE = slice(31, 37) >>> cost = int(record[SHARES]) * float(record[PRICE]) >>> cost 51325.0 >>>
1.12 序列中出現次數最多的元素
對于一個序列中每個元素的出現次數,當然可以自己手動利用字典去實作,但是最優的選擇應該是collections.Counter,它就是專門為這類問題而設計的,Counter物件的底層實作其實也是一個字典,具體使用見示例代碼,
>>> from collections import Counter >>> words = [ 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes', 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into', 'my', 'eyes', "you're", 'under' ] >>> word_counts = Counter(words) >>> word_counts.most_common(3) # 出現次數最多的3個單詞 [('eyes', 8), ('the', 5), ('look', 4)] >>> word_counts['eyes'] 8 >>> morewords = ['why','are','you','not','looking','in','my','eyes'] >>> for word in morewords:word_counts[word] += 1 # 像字典一樣操作Counter物件 >>> word_counts['eyes'] 9 >>> word_counts.update(morewords) # 或者使用update方法進行更新 >>> a = Counter(words) >>> b = Counter(morewords) >>> c = a + b # 可以使用+/-運算子進行操作 >>> c Counter({'eyes': 9, 'the': 5, 'look': 4, 'my': 4, 'into': 3, 'not': 2, 'around': 2, "don't": 1, "you're": 1, 'under': 1, 'why': 1, 'are': 1, 'you': 1, 'looking': 1, 'in': 1}) >>>
1.13 通過某個關鍵字排序一個字典串列
如果想要對一個元素為字典的串列進行排序操作,如sorted/max/min等函式,平常使用對應的lambda運算式即可,但是如果對性能有要求的話,建議使用operator.itemgetter函式,
如果排序的元素不是字典,而是類物件,則可以使用operator.attrgetter,這是1.14節的內容,用法與itemgetter相似,就不貼示例代碼了,
>>> from operator import itemgetter >>> rows = [ {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004} ] >>> sorted(rows, key=itemgetter('fname')) [{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}] >>> sorted(rows, key=itemgetter('lname','fname')) [{'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}] >>>
1.20 合并多個字典或映射
當你想在多個字典中查找某些鍵或值的時候可以使用collections.ChainMap,它會將多個字典從邏輯上合并為一個字典,如果多個字典中有相同的鍵,則對于該鍵的操作總是對應的擁有該鍵的第一個字典,需要注意的是對于ChainMap物件的操作是會作用到對應的字典上去的,
>>> from collections import ChainMap >>> a = {'x': 1, 'z': 3 } >>> b = {'y': 2, 'z': 4 } >>> c = ChainMap(a,b) >>> c['x'] 1 >>> c['y'] 2 >>> c['z'] 3 >>> len(c) 3 >>> list(c.keys()) ['x', 'z', 'y'] >>> list(c.values()) [1, 3, 2] >>> c['z'] 3 >>> c['z'] = 10 >>> c['z'] 10 >>> c['w'] = 40 >>> c['w'] 40 >>> a {'x': 1, 'z': 10, 'w': 40} >>>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/192497.html
標籤:Python
上一篇:教你閱讀Python開源專案代碼
下一篇:sklearn使用小貼士
