1. 把一個序列L拆分為包含n(n<=len(l))個單獨的變量
用法
data = ['ACME', 50, 90, (2017, 3, 8)]
name, shares, price, date = data
print(name, date)
name, _, _, (year, *_) = data # 只取某幾個元素而忽略其他元素
print(name, year)
ACME (2017, 3, 8)
ACME 2017
說明
做分解操作稠肘,有時可能需要丟棄某些值梧乘,通常可以選一個一般用不到的變量名來表示這些要被丟棄的元素咕缎,如可以用 '_'企蹭,'_', 'ign(ignored)', 'ign'颁虐。對于分解未知或者任意長度的可迭代對象時忽舟,使用這種*式的語法特別有用历谍。
例子
# 計算平均分時一般要去掉最高和最低分
def drop_first_last(grades):
first, *middle, last = grades
return avg(middle)
# 實現(xiàn)遞歸
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
2. 通過heapq模塊來找最大或最小的N個元素
用法
import heapq
import random
nums = random.sample(range(-20, 50), 10) # 從range(-20, 50)中隨機取出10個元素
print(nums)
print(heapq.nlargest(3, nums))
print(heapq.nsmallest(3, nums))
dict_nums = [dict.fromkeys('a', i) for i in nums]
print(dict_nums)
print(heapq.nlargest(3, dict_nums, key=lambda s: s['a'])) # 通過接受參數(shù)key虾标,可以在更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)上進行操作
print(heapq.nsmallest(3, dict_nums, key=lambda s: s['a']))
heap = list(nums)
heapq.heapify(heap) # 把nums以堆的順序進行排列
print(heap)
print(heapq.heappop(heap)) # heap[0]總是最小那個元素寓盗,heappop取出最小的元素,取出最小元素后會重新構(gòu)造堆
print(heapq.heappop(heap))
[-1, 43, 16, 47, 31, -11, 4, 49, 13, 28]
[49, 47, 43]
[-11, -1, 4]
[{'a': -1}, {'a': 43}, {'a': 16}, {'a': 47}, {'a': 31}, {'a': -11}, {'a': 4}, {'a': 49}, {'a': 13}, {'a': 28}]
[{'a': 49}, {'a': 47}, {'a': 43}]
[{'a': -11}, {'a': -1}, {'a': 4}]
[-11, 13, -1, 43, 28, 16, 4, 49, 47, 31]
-11
-1
說明
- 堆最重要的特性是heap[0]總是最小那個元素
- 當(dāng)要找的元素數(shù)量相對較小時,適用nlargest()和nsmallest()贞让,注意nlargest()和nsmallest()的實際實現(xiàn)會根據(jù)適用他們的不同方式而有所不同周崭,如N僅僅集合大小時會先排序
- 如果只是簡單的找到最小或最大的元素,則用min()和max()合適
- 如果N和集合本身大小差不多喳张,通常更快的方法是先對集合排序续镇,然后做切片操作
3. 實現(xiàn)優(yōu)先級隊列
問題
實現(xiàn)一個隊列,它能以給定的優(yōu)先級來對元素進行排序销部,每次pop操作都會返回優(yōu)先級最高的那個元素
解決方案
import heapq
class 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]
pq = PriorityQueue()
pq.push('jlan', 5)
pq.push('hua', 2)
pq.push('lann', 4)
pq.push('bob', 1)
pq.push('han', 3)
print(pq._queue)
print(pq.pop())
print(pq._queue)
print(pq.pop())
[(-5, 0, 'jlan'), (-3, 4, 'han'), (-4, 2, 'lann'), (-1, 3, 'bob'), (-2, 1, 'hua')]
jlan
[(-4, 2, 'lann'), (-3, 4, 'han'), (-2, 1, 'hua'), (-1, 3, 'bob')]
lann
說明(詳解見P10)
- 這個方案的核心在于heapq模塊的使用摸航。heappush()和heappop()分別從_queue中插入和移除,且保證列表中第一個元素的優(yōu)先級最低舅桩。heappop()總是返回‘最小’元素酱虎,因此這是隊列能彈出正確元素的關(guān)鍵。
- 在這段代碼中擂涛,隊列以元組(-priority, index, item)的形式組成读串,priority取負值是為了讓隊列能夠按優(yōu)先級從高到底排序(正常情況下,堆是按從小到大排序的),構(gòu)造堆時按-priority排序撒妈,當(dāng)priority相同時按index排序恢暖。
- 變量index的作用是為了將具有相同優(yōu)先級的元素以適當(dāng)?shù)捻樞蚺帕校ㄒ匀腙犿樞颍?/li>
字典操作
- 將鍵映射到多個值上
from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
print(d)
defaultdict(<class 'list'>, {'a': [1, 2]})
有序字典
使用collections.OrderedDict可以保持字典有序,OrderedDict內(nèi)部維護了一個雙向鏈表狰右,會根據(jù)元素加入的順序來排列鍵的位置杰捂。OrderedDict的大小是普通字典的2倍多。在字典上進行求最大值棋蚌,最小值等操作
prices = {
'apple': 2,
'banada': 3,
'orange': 1,
'peach': 4
}
# 在字典上執(zhí)行常見的操作嫁佳,只會處理鍵,而不是值
min(prices) # 返回'apple'
max(prices) # 返回'peach'
# 可以用dict.values()來處理值
min(prices.values()) # 返回 1
max(prices.values()) # 返回 4
min(prices, key=lambda x: prices[x]) # 返回'orange'
max(prices, key=lambda x: prices[x]) # 返回'peach'
# 對字典進行求最大值谷暮,最小值等操作一般用下邊的方法
min(zip(prices.values(), prices.keys())) # 返回(1, 'orange')
max(zip(prices.values(), prices.keys())) # 返回(4, 'orange')
# zip()創(chuàng)建了一個迭代器蒿往,其內(nèi)容只能被消費一次
# 涉及(value, key)對的比較時,如果多個條目有相同的value坷备,此時將根據(jù)key進行判定
(4, 'peach')
- 在字典中尋找相同點
# 找出兩個字典可能相同的地方(相同的鍵或者值)
a = {'x': 1, 'y': 2, 'z': 3}
b = {'w': 11, 'y': 2, 'z': 13}
# a和b相同的鍵
a.keys() & b.keys() # 返回 {'y', 'z'}
# 在a中但是不在b中的鍵
a.keys() - b.keys() # 返回 {'x'}
# a和b中相同的{key: value}
a.items() & b.items() # 返回 {('y', 2)}
{('y', 2)}