python dict根据value找对应的key_一个不得不了解的Python库——collections
基本介紹
Python擁有一些內(nèi)置的數(shù)據(jù)類型,比如str, int, list, tuple, dict等, collections模塊在這些內(nèi)置數(shù)據(jù)類型的基礎(chǔ)上,提供了幾個(gè)額外的數(shù)據(jù)類型,如下。這些類在平時(shí)Python代碼中用處非常大,熟練掌握這個(gè)模塊,可以大大簡化Python代碼,提高Python代碼逼格。
import collections
print collections.__all__
['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict', 'Hashable','Iterable', 'Iterator', 'Sized', 'Container','Callable', 'Set', 'MutableSet','Mapping', 'MutableMapping', 'MappingView', 'KeysView', 'ItemsView', 'ValuesView', 'Sequence', 'MutableSequence']
本文主要介紹collections庫中常用的幾個(gè)類:
- Counter: 計(jì)數(shù)器,主要用來計(jì)數(shù)
- deque: 雙端隊(duì)列,可以快速的從另外一側(cè)追加和推出對象
- OrderedDict: 有序字典
- namedtuple: 生成可以使用名字來訪問元素內(nèi)容的tuple子類
- defaultdict: 帶有默認(rèn)值的字典
Counter類
Counter類的目的是用來跟蹤值出現(xiàn)的次數(shù)。它是一個(gè)無序的容器類型,以字典的鍵值對形式存儲,其中元素作為key,其計(jì)數(shù)作為value。計(jì)數(shù)值可以是任意的Interger(包括0和負(fù)數(shù))。
Counter類的創(chuàng)建
from collections import Counter
c1 = Counter() # 創(chuàng)建一個(gè)空的Counter類
c2 = Counter('zhongguo') # 從一個(gè)可iterable對象(list、tuple、dict、字符串等)創(chuàng)建
c3 = Counter({'a': 5, 'b': 1}) # 從一個(gè)字典對象創(chuàng)建
c4= Counter(a=3, b=8) # 從一組鍵值對創(chuàng)
most_common()方法
s = 'Nothing is difficult if you put your heart into it'
c = Counter(s)
print c.most_common(5)
[(' ', 9), ('i', 7), ('t', 6), ('o', 4), ('u', 4)]
鍵值的訪問與計(jì)數(shù)器的更新
c = Counter("zhongguo")
print c['z'],c['o'],c['l']
output:1,2,0
#注意:不同于字典鍵值查找,當(dāng)查找的鍵值不存在是計(jì)數(shù)器返回為0
#第一種更新方式--updatez增加
c.update('ren') # 使用另一個(gè)iterable對象更新
print c['n'] #2
d = Counter('niubi')
c.update(d) # 使用另一個(gè)Counter對象更新
print c['n'] #4
#第2種更新方式--subtract減少
c = Counter("zhongguo")
c.subtract('ren')
print c['n'] #0
d = Counter('niubi')
c.update(d)
print c['n'] #-1(是可以為負(fù)數(shù)的)
elements()方法以及刪除鍵值
c = Counter(a=2, b=1, c=0, d=-1)
list(c.elements())
#['a', 'a', 'b'] #小于或等于0的不顯示了
#刪除鍵值
del c['a']
print c
#Counter({'b': 1, 'c': 0, 'd': -1})
一些基本操作
c1 = Counter(a=1, b=2)
c2 = Counter(a=2, b=3)
print c1+c2
print c1-c2 #不返回0或者負(fù)數(shù)計(jì)數(shù)
#Counter({'b': 5, 'a': 3})
#Counter()
sum(c.values()) # 所有計(jì)數(shù)的總數(shù)
c.clear() # 重置Counter對象,注意不是刪除
list(c) # 將c中的鍵轉(zhuǎn)為列表
set(c) # 將c中的鍵轉(zhuǎn)為set
dict(c) # 將c中的鍵值對轉(zhuǎn)為字典
c += Counter() # 移除0和負(fù)值
defaultdict 類
defaultdict 是 dict 的子類,因此 defaultdict 也可被當(dāng)成 dict 來使用,dict 支持的功能,defaultdict 基本都支持。但它與 dict 最大的區(qū)別在于,如果程序試圖根據(jù)不存在的 key 采訪問 dict 中對應(yīng)的 value,則會引發(fā) KeyError 異常;而 defaultdict 則可以提供一個(gè) default_factory 屬性,該屬性所指定的函數(shù)負(fù)責(zé)為不存在的 key 來生成 value。
from collections import defaultdict
my_dict = {}
# 使用int作為defaultdict的default_factory
# 將key不存在時(shí),將會返回int()函數(shù)的返回值
my_defaultdict = defaultdict(int)
print my_defaultdict['a'] # 0
print my_dict['a'] # KeyError
#與Counter性質(zhì)類似
#上面分別創(chuàng)建了空的 dict 對象和 defaultdict 對象,當(dāng)程序試圖訪問 defaultdict 中不存在的 key 對應(yīng)的 value 時(shí),程序輸出 defaultdict 的 default_factory 屬性(int 函數(shù))的返回值 0;如果程序試圖訪問 dict 中不存在的 key 對應(yīng)的 value,就會引發(fā) KeyError異常。
對比dict操作
###dict####
s = [('Python', 1), ('Swift', 2), ('Python', 3), ('Swift', 4), ('Python', 9)]
d = {}
for k, v in s:
# setdefault()方法用于獲取指定key對應(yīng)的value.
# 如果該key不存在,則先將該key對應(yīng)的value設(shè)置為默認(rèn)值:[]
d.setdefault(k, []).append(v)
print list(d.items())
#需要處理 key 不存在的情況,如果該key不存在,setdefault()方法就會先為該key設(shè)置一個(gè)默認(rèn)的value。
###defaultdict###
s = [('Python', 1), ('Swift', 2), ('Python', 3), ('Swift', 4), ('Python', 9)]
# 創(chuàng)建defaultdict,設(shè)置由list()函數(shù)來生成默認(rèn)值
d = defaultdict(list)
for k, v in s:
# 直接訪問defaultdict中指定key對應(yīng)的value即可。
# 如果該key不存在,defaultdict會自動為該key生成默認(rèn)值
d[k].append(v)
print(list(d.items()))
相比于普通dict是不是方便很多。
deque類
deque是一個(gè)雙向鏈表,針對list連續(xù)的數(shù)據(jù)結(jié)構(gòu)插入和刪除進(jìn)行優(yōu)化。它提供了兩端都可以操作的序列,這表示在序列的前后你都可以執(zhí)行添加或刪除操作。
from collections import deque
d=deque()
類似于list方法
d.append(3)
d.append(8)
print d
#deque([3,8])
print len(d) #2,
d[0] #3
d[-1] #8
d.pop() #5,默認(rèn)pop()拋出的是隊(duì)列的最后一個(gè)元素
d.leftpop() #3
長度限制
d=deque(maxlen=10)
for i in range(20):
d.append(i)
#deque(10, 11, 12, 13, 14, 15, 16', 17, 18, 19, 20], maxlen=10)
#當(dāng)限制長度的deque增加超過限制數(shù)時(shí),左邊會自動刪除,這也符合隊(duì)列的性質(zhì)。
extend()方法
d=deque([1,2,3,4,5])
d.extend([6])
#deque([1,2,3,4,5,6])
d.extendleft([-2,-1,0])
#deque([-2,-1,0, 1, 2, 3, 4, 5, 6])
rotate()方法
b=deque("ABCDEFG")
print b
b.rotate(2)
print b
b.rotate(3)
print b
#deque(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
#deque(['F', 'G', 'A', 'B', 'C', 'D', 'E'])
#deque(['C', 'D', 'E', 'F', 'G', 'A', 'B'])
OrderedDict類
OrderedDict 也是 dict 的子類,其最大特征是,它可以“維護(hù)”添加 key-value 對的順序。簡單來說,就是先添加的 key-value 對排在前面,后添加的 key-value 對排在后面。相比于dict更加靈活。
基礎(chǔ)性質(zhì)
from collections import OrderedDict
# 創(chuàng)建OrderedDict對象
dx = OrderedDict(b=5, c=2, a=7)
print dx # OrderedDict([('b', 5), ('c', 2), ('a', 7)])
d = OrderedDict()
# 向OrderedDict中添加key-value對
d['Python'] = 89
d['Swift'] = 92
d['Kotlin'] = 97
d['Go'] = 87
# 遍歷OrderedDict的key-value對
for k,v in d.items():
print k, v
順序
# 創(chuàng)建普通的dict對象
my_data = {'Python': 20, 'Swift':32, 'Kotlin': 43, 'Go': 25}
# 創(chuàng)建基于key排序的OrderedDict
d1 = OrderedDict(sorted(my_data.items(), key=lambda t: t[0]))
# 創(chuàng)建基于value排序的OrderedDict
d2 = OrderedDict(sorted(my_data.items(), key=lambda t: t[1]))
print(d1) # OrderedDict([('Go', 25), ('Kotlin', 43), ('Python', 20), ('Swift', 32)])
print(d2) # OrderedDict([('Python', 20), ('Go', 25), ('Swift', 32), ('Kotlin', 43)])
print(d1 == d2) # False
# OrderedDict能維護(hù)key-value對的添加順序,因此即使兩個(gè) OrderedDict中的key-value對完全相同,但只要順序不同,程序在判斷它們是否相等時(shí)也依然會返回false
特殊方法
d = OrderedDict.fromkeys('abcde')
# 將b對應(yīng)的key-value對移動到最右邊(最后加入)
d.move_to_end('b')
print(d.keys()) # odict_keys(['a', 'c', 'd', 'e', 'b'])
# 將b對應(yīng)的key-value對移動到最左邊(最先加入)
d.move_to_end('b', last=False)
print(d.keys()) # odict_keys(['b', 'a', 'c', 'd', 'e'])
# 彈出并返回最右邊(最后加入)的key-value對
print(d.popitem()[0]) # e
# 彈出并返回最左邊(最先加入)的key-value對
print(d.popitem(last=False)[0]) # b
namedtuple類
namedtuple() 是一個(gè)工廠函數(shù),使用該函數(shù)可以創(chuàng)建一個(gè) tuple 類的子類,該子類可以為 tuple 的每個(gè)元素都指定宇段名,這樣程序就可以根據(jù)字段名來訪問 namedtuple 的各元素了,也可以根據(jù)索引來訪問 namedtuple 的各元素。
基本屬性
namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)
- typename:該參數(shù)指定所創(chuàng)建的 tuple 子類的類名,相當(dāng)于用戶定義了一個(gè)新類。
- field_names:該參數(shù)是一個(gè)字符串序列,如 ['x','y']。此外,field_names 也可直接使用單個(gè)字符串代表所有字段名,多個(gè)字段名用空格、逗號隔開,如 'x y' 或 'x,y'。任何有效的 Python 標(biāo)識符都可作為字段名(不能以下畫線開頭)。有效的標(biāo)識符可由字母、數(shù)字、下畫線組成,但不能以數(shù)字、下面線開頭,也不能是關(guān)鍵字(如 return、global、pass、raise 等)。
- rename:如果將該參數(shù)設(shè)為 True,那么無效的字段名將會被自動替換為位置名。例如指定 ['abc','def','ghi','abc'],它將會被替換為 ['abc', '_1','ghi','_3'],這是因?yàn)?def 字段名是關(guān)鍵字,而 abc 字段名重復(fù)了。
- verbose:如果該參數(shù)被設(shè)為 True,那么當(dāng)該子類被創(chuàng)建后,該類定義就被立即打印出來。
- module:如果設(shè)置了該參數(shù),那么該類將位于該模塊下,因此該自定義類的 __module__ 屬性將被設(shè)為該參數(shù)值。
from collections import namedtuple
# 定義命名元組類:Point
Point = namedtuple('Point', ['x', 'y'])
# 初始化Point對象,即可用位置參數(shù),也可用命名參數(shù)
p = Point(11, y=22)
# 像普通元組一樣用根據(jù)索引訪問元素
print(p[0] + p[1]) # 33
# 執(zhí)行元組解包,按元素的位置解包
a, b = p
print(a, b) # 11, 22
# 根據(jù)字段名訪問各元素
print(p.x + p.y) # 33
print(p) # Point(x=11, y=22)
方法
- _make(iterable):類方法。該方法用于根據(jù)序列或可迭代對象創(chuàng)建命名元組對象。
- _asdict():將當(dāng)前命名元組對象轉(zhuǎn)換為 OrderedDict 字典。
- _replace(**kwargs):替換命名元組中一個(gè)或多個(gè)字段的值。
- _source:該屬性返回定義該命名元組的源代碼。
- _fields:該屬性返回該命名元組中所有字段名組成的元組。
my_data = ['East', 'North']
# 創(chuàng)建命名元組對象
p2 = Point._make(my_data)
print(p2) # Point(x='East', y='North')
# 將命名元組對象轉(zhuǎn)換成OrderedDict
print(p2._asdict()) # OrderedDict([('x', 'East'), ('y', 'North')])
# 替換命名元組對象的字段值
p2._replace(y='South')
print(p2) # Point(x='East', y='North')
# 輸出p2包含的所有字段
print(p2._fields) # ('x', 'y')
# 再次定義一個(gè)命名元組類
Color = namedtuple('Color', 'red green blue')
# 再次定義命名元組類,其字段由Point的字段加上Color的字段
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
# 創(chuàng)建Pixel對象,分別為x、y、red、green、blue字段賦值
pix = Pixel(11, 22, 128, 255, 0)
print(pix) # Pixel(x=11, y=22, red=128, green=255, blue=0)
總結(jié)
看過上面的介紹是不是對collections模塊有一定的理解了,是不是也已經(jīng)知道了它的重要性,總之一句話,理解這個(gè)模塊的各種方法實(shí)現(xiàn),能夠讓你的代碼有事半功倍的效果,而且相比傳統(tǒng)的list,dict,用它可以讓你的代碼逼格更高,數(shù)不多說,快去學(xué)習(xí)了。
總結(jié)
以上是生活随笔為你收集整理的python dict根据value找对应的key_一个不得不了解的Python库——collections的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不同工作组能访问吗_“辣椒”的辣味从哪里
- 下一篇: go interface转int_32.