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