標籤:元素 class log 切片 div str 操作 擴充 heap
1、解壓序列賦值給多個變數
任何的序列(或者是可迭代對象)可以通過一個簡單的指派陳述式解壓並賦值給多個變數。 唯一的前提就是變數的數量必須跟序列元素的數量是一樣的。
>>> data = [ ‘ACME‘, 50, 91.1, (2012, 12, 21) ]
>>> name, shares, price, date = data>>> name, shares, price, (year, mon, day) = data>>> name‘ACME‘>>> year2012
如果一個可迭代對象的元素個數超過變數個數時,會拋出一個 ValueError 。可以用*來解決,這個僅支援python3。擴充的迭代解壓文法是專門為解壓不確定個數或任意個數元素的可迭代對象而設計的。解壓出來的始終是列表,如果為空白則為空白列表。
>>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]>>> trailing[10, 8, 7, 1, 9, 5, 10]>>> current3>>> first, *middle, last = grades>>> record = (‘ACME‘, 50, 123.45, (12, 18, 2012))>>> name, *_, (*_, year) = record>>> name‘ACME‘>>> year2012
2、隊列
collections.deque可以產生固定大小,或不限大小的隊列。你可以在隊列的兩端執行添加和彈出元素的操作。在隊列兩端插入或刪除元素時間複雜度都是 O(1) ,而在列表的開頭插入或刪除元素的時間複雜度為 O(N) 。
>>> q = deque(maxlen=2)>>> q.append(1)>>> q.append(2)>>> qdeque([1, 2], maxlen=2)>>> q.append(3)>>> qdeque([2, 3], maxlen=2)>>> q = deque()>>> q.append(1)>>> q.append(2)>>> qdeque([1, 2])>>> q.appendleft(3)>>> qdeque([3, 1, 2])>>> q.pop()2>>> qdeque([3, 1])>>> q.popleft()3
3、尋找最大和最小的N個元素
heapq模組有兩個函數:nlargest() 和 nsmallest() 可以解決這個問題。它們的傳回值是一個列表。支援關鍵字參數。
import heapqnums = [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},]cheap = heapq.nsmallest(3, portfolio, key=lambda s: s[‘price‘])expensive = heapq.nlargest(3, portfolio, key=lambda s: s[‘price‘])
注意:當要尋找的元素個數相對比較小的時候,函數 nlargest() 和 nsmallest() 是很合適的; 如果你僅僅想尋找唯一的最小或最大(N=1)的元素的話,那麼使用 min() 和 max() 函數會更快些;如果N的大小和集合大小接近的時候,通常先排序這個集合然後再使用切片操作會更快點。
在底層實現裡面,首先會先將集合資料進行堆排序後放入一個列表中:
>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]>>> import heapq>>> heapq.heapify(nums)>>> nums[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]>>> heapq.heappop(nums)-4>>> heapq.heappop(nums)1>>> heapq.heappop(nums)2
堆資料結構最重要的特徵是 heap[0] 永遠是最小的元素。並且剩餘的元素可以很容易的通過調用 heapq.heappop() 方法得到, 該方法會先將第一個元素彈出來,然後用下一個最小的元素來取代被彈出元素(這種操作時間複雜度僅僅是O(log N),N是堆大小)。
3、實現一個優先順序隊列
每次pop操作總是返回優先順序最高的那個。
import heapqclass PriorityQueue: def __init__(self): self._queue = [] self._index = 0 def push(self, item, priority): heapq.heappush(self._queue, (-priority, self._index, item)) self._index += 1 def pop(self): return heapq.heappop(self._queue)[-1]
使用方式
>>> q = PriorityQueue()>>> q.push(‘foo‘, 1)>>> q.push(‘bar‘, 5)>>> q.push(‘spam‘, 4)>>> q.push(‘grok‘, 1)>>> q.pop()‘bar‘>>> q.pop()‘spam‘
_queue中放的元素是tuple,tuple的大小是比較第一個元素大小,如果相同再比較下一個元素。tuple中加入_index是為了將priority相同的元素,按照push先後順序區分開來,同時也避免如果item不支援比較大小會出現錯誤的情況。-priority將優先順序取反,保證隊列中最小的元素函數(priority最大)總是放在_queue[0]。 heapq.heappush() 和 heapq.heappop() 分別在隊列 _queue 上插入和刪除第一個元素, 操作後,_queue第一個元素總是最小的,從而保證隊列_queue第一個元素擁有最高優先順序。
參考:《Python Cookbook》3rd Edition
http://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
Python學習筆記——資料結構和演算法(一)