cookbook 數(shù)據(jù)結(jié)構(gòu)和算法(一)

deque 類(lèi)可以被用在任何只需要一個(gè)簡(jiǎn)單隊(duì)列數(shù)據(jù)結(jié)構(gòu)的場(chǎng)合,如果
不設(shè)置最大隊(duì)列大小(maxlen),那么就會(huì)得到一個(gè)無(wú)限大小隊(duì)列,你可以在隊(duì)列的兩端執(zhí)行添加和彈出元素的操作

Collections 中有不少挺實(shí)用的模塊,比如deque
使用list存儲(chǔ)數(shù)據(jù)時(shí),按索引訪(fǎng)問(wèn)元素很快,只是插入和刪除元素比較慢,deque就是為了高效實(shí)現(xiàn)插入和刪除操作的雙向列表,適合用于隊(duì)列和棧。

deque除了實(shí)現(xiàn)list的append()pop()外,還支持appendleft()popleft(),這樣就可以非常高效地往頭部添加或刪除元素。

li = deque(li)
li.append('x')
li.appendleft('y')
print(li) # deque(['y', '1', 'a', 'b', 'c', 'x'])

下面為cookbook中的例子: 保存有限歷史紀(jì)錄

from collections import deque
def search(lines, pattern, history=5):
    previous_lines = deque(maxlen=history) #  構(gòu)建一個(gè)固定大小的隊(duì)列. 當(dāng)新的元素加入并且這個(gè)隊(duì)列已滿(mǎn)的時(shí)候,前面的元素就會(huì)被移除掉, 這個(gè)邏輯,嗯嗯,happy的使用。 
    for li in lines:
        if pattern in li:
            yield li, previous_lines
        previous_lines.append(li)

if __name__ == '__main__':
    with open(r'somefile.txt') as f:
        for line, prevlines in search(f, 'Python', 5):
            for pline in prevlines:
                print(pline, end='')
            print(line, end='')
            print('-' * 20)

從一個(gè)集合中獲取最大或者最小的N個(gè)元素的集合?
答: 使用heapq模塊,如下所示:

import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
print(heapq.nlargest(3,nums)) # [42, 37, 23]
print(heapq.nsmallest(2,nums))# [-4, 1]
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} ]

print(heapq.nlargest(3, portfolio, key=lambda x:x['price'])) 
#[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]

print(heapq.nsmallest(2, portfolio, key=lambda x:x['shares']))
#[{'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}]

其實(shí)取最大或者最小,有幾種方法可以使用,按需?。?/p>

  • sorted(items)[:N] orsorted(items)[-N:]
  • min() or max()
  • heapq.nlargest() or heapq.nsmallest()

字典中的鍵映射多個(gè)值

l = [('a',2),('b',3),('a',1),('b',4),('a',3),('a',1),('b',3)]
from collections import defaultdict

d = defaultdict(list)
for key,value in l:
 d[key].append(value)
print(d)

輸出:defaultdict(<class 'list'>, {'a': [2, 1, 3, 1], 'b': [3, 4, 3]})

字典排序
可以使用Collections中的OrderedDict類(lèi).

d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"
for key in d:
    print(key, d[key])

比如想精確控制編碼后的字段的順序,就可以先使用OrderDict來(lái)構(gòu)建這樣的數(shù)據(jù)

import json
print(json.dumps(d))

字典的運(yùn)算
在字典中做一些操作,比如求最大值,最小值,排序等等
巧用zip()與lambda.

prices = { 'ACME': 45.23, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.20, 'FB': 10.75}
min_price = min(zip(prices.values(),prices.keys()))
#min_price = list(zip(prices.values(),prices.keys()))
print(min_price)
#  排序 
prices_sorted = sorted(zip(prices.values(), prices.keys()))
print(prices_sorted)
#在 min() 和 max() 函數(shù)中提供 key 函數(shù)參數(shù)來(lái)獲取最小值或最大值對(duì)應(yīng)的鍵的信息
print(min(prices, key=lambda k: prices[k])) # Returns 'FB'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容