python數(shù)據(jù)結(jié)構(gòu)

Python CookBook總結(jié)

保留最后N 個(gè)元素

使用deque(maxlen=N) 構(gòu)造函數(shù)會(huì)新建一個(gè)固定大小的隊(duì)列。當(dāng)新的元素加入并且這個(gè)隊(duì)列已滿的時(shí)候葫笼,最老的元素會(huì)自動(dòng)被移除掉。

from collections import deque
def search(lines, pattern, history=5):
    previous_lines = deque(maxlen=history)
    for li in lines:
        if pattern in li:
        yield li, previous_lines
    previous_lines.append(li)

怎樣從一個(gè)集合中獲得最大或者最小的N 個(gè)元素列表奕谭?

import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]
print(heapq.nsmallest(3, nums)) # Prints [-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}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])

怎樣實(shí)現(xiàn)一個(gè)鍵對(duì)應(yīng)多個(gè)值的字典(也叫multidict )撵幽?

from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)

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

字典排序斯稳,你想創(chuàng)建一個(gè)字典,并且在迭代或序列化這個(gè)字典的時(shí)候能夠控制元素的順序庄萎。

from collections import OrderedDict
def ordered_dict():
    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])

字典運(yùn)算踪少,怎樣在數(shù)據(jù)字典中執(zhí)行一些計(jì)算操作(比如求最小值、最大值糠涛、排序等等)援奢?

prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
#為了對(duì)字典值執(zhí)行計(jì)算操作,通常需要使用zip() 函數(shù)先將鍵和值
#反轉(zhuǎn)過來忍捡。比如集漾,下面是查找最小和最大股票價(jià)格和股票值的代碼:
min_price = min(zip(prices.values(), prices.keys()))
# min_price is (10.75, 'FB')
max_price = max(zip(prices.values(), prices.keys()))
# max_price is (612.78, 'AAPL')

prices_sorted = sorted(zip(prices.values(), prices.keys()))
# prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
# (45.23, 'ACME'), (205.55, 'IBM'),
# (612.78, 'AAPL')]
#注意:zip() 函數(shù)創(chuàng)建的是一個(gè)只能訪問一次的迭代器

查找兩字典的相同點(diǎn)

#python2.7需將列表加上set()轉(zhuǎn)為集合
a = {'x' : 1,'y' : 2,'z' : 3}
b = {'w' : 10,'x' : 11,'y' : 2}
# Find keys in common
a.keys() & b.keys() # { 'x', 'y' }
# Find keys in a that are not in b
a.keys() - b.keys() # { 'z' }
# Find (key,value) pairs in common
a.items() & b.items() # { ('y', 2) }
#這些操作也可以用于修改或者過濾字典元素切黔。比如,假如你
#想以現(xiàn)有字典構(gòu)造一個(gè)排除幾個(gè)指定鍵的新字典帆竹。下面利用字典推導(dǎo)來實(shí)現(xiàn)這樣的需求:
# Make a new dictionary with certain keys removed
c = {key:a[key] for key in a.keys() - {'z', 'w'}}
# c is {'x': 1, 'y': 2}

命名切片

#內(nèi)置的slice() 函數(shù)創(chuàng)建了一個(gè)切片對(duì)象
>>> a = slice(5, 50, 2)
>>> a.start
5
>>> a.stop
50
>>> a.step
2
record = '....................100 .......513.25 ..........'
SHARES = slice(20, 23)
PRICE = slice(31, 37)
cost = int(record[SHARES]) * float(record[PRICE])
#你還能通過調(diào)用切片的indices(size) 方法將它映射到一個(gè)確定大小的序
#列上绕娘,這個(gè)方法返回一個(gè)三元組(start, stop, step) ,所有值都會(huì)
#被合適的縮小以滿足邊界限制栽连,從而使用的時(shí)候避免出現(xiàn)IndexError 異常
>>> s = 'HelloWorld'
>>> a.indices(len(s))
(5, 10, 2)
>>> for i in range(*a.indices(len(s))):
... print(s[i])

序列中出現(xiàn)次數(shù)最多的元素

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'
]
from collections import Counter
word_counts = Counter(words)
# 出現(xiàn)頻率最高的3 個(gè)單詞
top_three = word_counts.most_common(3)
print(top_three)
# Outputs [('eyes', 8), ('the', 5), ('look', 4)]

#Counter 實(shí)例一個(gè)鮮為人知的特性是它們可以很容易的跟數(shù)學(xué)運(yùn)算操作相結(jié)合险领。比如:
>>> a = Counter(words)
>>> b = Counter(morewords)
>>> a
Counter({'eyes': 8, 'the': 5, 'look': 4, 'into': 3, 'my': 3, 'around': 2,
"you're": 1, "don't": 1, 'under': 1, 'not': 1})
>>> b
Counter({'eyes': 1, 'looking': 1, 'are': 1, 'in': 1, 'not': 1, 'you': 1,
'my': 1, 'why': 1})
>>> # Combine counts
>>> c = a + b
>>> c
Counter({'eyes': 9, 'the': 5, 'look': 4, 'my': 4, 'into': 3, 'not': 2,
'around': 2, "you're": 1, "don't": 1, 'in': 1, 'why': 1,
'looking': 1, 'are': 1, 'under': 1, 'you': 1})
>>> # Subtract counts
>>> d = a - b
>>> d
Counter({'eyes': 7, 'the': 5, 'look': 4, 'into': 3, 'my': 2, 'around': 2,
"you're": 1, "don't": 1, 'under': 1})
>>>

通過某個(gè)關(guān)鍵字排序一個(gè)字典列表

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}
]
from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print(rows_by_uid)
#itemgetter() 有時(shí)候也可以用lambda 表達(dá)式代替
rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))

>>> min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>> max(rows, key=itemgetter('uid'))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
>>>

通過某個(gè)字段將記錄分組

你有一個(gè)字典或者實(shí)例的序列,然后你想根據(jù)某個(gè)特定的字段比如date 來分組迭代訪問秒紧。

#itertools.groupby() 函數(shù)對(duì)于這樣的數(shù)據(jù)分組操作非常實(shí)用
rows = [
{'address': '5412 N CLARK', 'date': '07/01/2012'},
{'address': '5148 N CLARK', 'date': '07/04/2012'},
{'address': '5800 E 58TH', 'date': '07/02/2012'},
{'address': '2122 N CLARK', 'date': '07/03/2012'},
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
{'address': '1060 W ADDISON', 'date': '07/02/2012'},
{'address': '4801 N BROADWAY', 'date': '07/01/2012'},
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]
from operator import itemgetter
from itertools import groupby
# Sort by the desired field first
rows.sort(key=itemgetter('date'))
# Iterate in groups
for date, items in groupby(rows, key=itemgetter('date')):
    print(date)
    for i in items:
        print(' ', i)

運(yùn)行結(jié)果:
07/01/2012
{'date': '07/01/2012', 'address': '5412 N CLARK'}
{'date': '07/01/2012', 'address': '4801 N BROADWAY'}
07/02/2012
{'date': '07/02/2012', 'address': '5800 E 58TH'}
{'date': '07/02/2012', 'address': '5645 N RAVENSWOOD'}
{'date': '07/02/2012', 'address': '1060 W ADDISON'}
07/03/2012
{'date': '07/03/2012', 'address': '2122 N CLARK'}
07/04/2012
{'date': '07/04/2012', 'address': '5148 N CLARK'}
{'date': '07/04/2012', 'address': '1039 W GRANVILLE'}

過濾序列元素

#最簡(jiǎn)單的過濾序列元素的方法就是使用列表推導(dǎo)绢陌。比如:
>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> [n for n in mylist if n > 0]
[1, 4, 10, 2, 3]
>>> [n for n in mylist if n < 0]
[-5, -7, -1]
>>>
#使用列表推導(dǎo)的一個(gè)潛在缺陷就是如果輸入非常大的時(shí)候會(huì)產(chǎn)生一個(gè)非常大的結(jié)果集,占用大量?jī)?nèi)存熔恢。如果你對(duì)內(nèi)存比較敏感脐湾,那么你可以使生成器表達(dá)式迭代產(chǎn)生過濾的元素。比如:
>>> pos = (n for n in mylist if n > 0)
>>> pos
<generator object <genexpr> at 0x1006a0eb0>
>>> for x in pos:
... print(x)
...
14
10
23
>>>
#filter函數(shù)
values = ['1', '2', '-3', '-', '4', 'N/A', '5']
def is_int(val):
try:
    x = int(val)
    return True
except ValueError:
    return False
ivals = list(filter(is_int, values))
print(ivals)
# Outputs ['1', '2', '-3', '4', '5']

從字典中提取子集

prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}#
Make a dictionary of all prices over 200
p1 = {key: value for key, value in prices.items() if value > 200}
# Make a dictionary of tech stocks
tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
p2 = {key: value for key, value in prices.items() if key in tech_names}

映射名稱到序列元素

>>> from collections import namedtuple
>>> Subscriber = namedtuple('Subscriber', ['addr', 'joined'])
>>> sub = Subscriber('jonesy@example.com', '2012-10-19')
>>> sub
Subscriber(addr='jonesy@example.com', joined='2012-10-19')
>>> sub.addr
'jonesy@example.com'
>>> sub.joined
'2012-10-19'
>>>

轉(zhuǎn)換并同時(shí)計(jì)算數(shù)據(jù),一個(gè)非常優(yōu)雅的方式去結(jié)合數(shù)據(jù)計(jì)算與轉(zhuǎn)換就是使用一個(gè)生成器表達(dá)式參數(shù)

nums = [1, 2, 3, 4, 5]
s = sum(x * x for x in nums)
# Determine if any .py files exist in a directory
import os
files = os.listdir('dirname')
if any(name.endswith('.py') for name in files):
print('There be python!')
else:
print('Sorry, no python.')
# Output a tuple as CSV
s = ('ACME', 50, 123.45)
print(','.join(str(x) for x in s))
# Data reduction across fields of a data structure
portfolio = [
{'name':'GOOG', 'shares': 50},
{'name':'YHOO', 'shares': 75},
{'name':'AOL', 'shares': 20},
{'name':'SCOX', 'shares': 65}
]
min_shares = min(s['shares'] for s in portfolio)

合并多個(gè)字典或映射

a = {'x': 1, 'z': 3 }
b = {'y': 2, 'z': 4 }
from collections import ChainMap
c = ChainMap(a,b)
print(c['x']) # Outputs 1 (from a)
print(c['y']) # Outputs 2 (from b)
print(c['z']) # Outputs 3 (from a)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叙淌,一起剝皮案震驚了整個(gè)濱河市秤掌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹰霍,老刑警劉巖闻鉴,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茂洒,居然都是意外死亡孟岛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門督勺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渠羞,“玉大人,你說我怎么就攤上這事智哀〈窝” “怎么了?”我有些...
    開封第一講書人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵瓷叫,是天一觀的道長(zhǎng)屯吊。 經(jīng)常有香客問我,道長(zhǎng)赞辩,這世上最難降的妖魔是什么雌芽? 我笑而不...
    開封第一講書人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮辨嗽,結(jié)果婚禮上世落,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好屉佳,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開白布谷朝。 她就那樣靜靜地躺著,像睡著了一般武花。 火紅的嫁衣襯著肌膚如雪圆凰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,807評(píng)論 1 314
  • 那天体箕,我揣著相機(jī)與錄音专钉,去河邊找鬼。 笑死累铅,一個(gè)胖子當(dāng)著我的面吹牛跃须,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娃兽,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼菇民,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了投储?” 一聲冷哼從身側(cè)響起第练,我...
    開封第一講書人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎玛荞,沒想到半個(gè)月后娇掏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冲泥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年驹碍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壁涎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凡恍。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖怔球,靈堂內(nèi)的尸體忽然破棺而出嚼酝,到底是詐尸還是另有隱情,我是刑警寧澤竟坛,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布闽巩,位于F島的核電站,受9級(jí)特大地震影響担汤,放射性物質(zhì)發(fā)生泄漏涎跨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一崭歧、第九天 我趴在偏房一處隱蔽的房頂上張望隅很。 院中可真熱鬧,春花似錦率碾、人聲如沸叔营。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绒尊。三九已至畜挥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間婴谱,已是汗流浹背蟹但。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谭羔,地道東北人矮湘。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像口糕,于是被迫代替她去往敵國和親缅阳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容