Python collections模塊總結


Python collections模塊總結

除了我們使用的那些基礎的數據結構,還有包括其它的一些模塊提供的數據結構,有時甚至比基礎的數據結構還要好用。

collections

ChainMap

這是一個為多個映射創建單一視圖的類字典類型,也就是說,它同樣具有字典類型的方法,它比基礎數據結構中的字典的創建和多次更新要快,需要注意的是,增刪改的操作都只會針對該對象的第一個字典,其余字典不會發生改變,但是如果是查找,則會在多個字典中查找,直到找到第一個出現的key為止。

特有方法 解釋
maps 返回全部的字典(這個列表中至少存在一個列表)
new_child 在字典列表頭部插入字典,如果其參數為空,則會默認插入一個空字典,並且返回一個改變后的ChainMap對象
parents 返回除了第一個字典的其余字典列表的ChainMap對象,可以用來查詢除了第一個列表以外的內容。
import collections
a = {1: 2, 2: 3}
b = {1: 3, 3: 4, 4: 5}
chains = collections.ChainMap(a, b)
# maps
# 注意maps是個屬性,不是一個方法,其改變
print(chains.maps)  # [{1: 2, 2: 3}, {1: 3, 3: 4, 4: 5}]
# get
assert chains.get(1, -1) == 2
# parents
# 從第二個map開始找
assert chains.parents.get(1, -1) == 3
# popitem
assert chains.popitem() == (2, 3)
# pop
# 返回的是value
assert chains.pop(1) == 2
# new_child
assert chains.new_child()
print(chains.maps)  # [{}, {1: 3, 3: 4, 4: 5}]
chains[2] = 1
print(chains.maps)  # [{2: 1}, {1: 3, 3: 4, 4: 5}]
# setdedault
# 如果已經存在key,則不會添加
assert chains.setdefault(1, 10) == 3
# update
chains.update({2: 4, 3: 5})
print(chains.maps)  # [{1: 2, 2: 4, 3: 5}, {1: 3, 3: 4, 4: 5}]
# keys
print(chains.keys())  # KeysView(ChainMap({2: 4, 3: 5}, {1: 3, 3: 4, 4: 5}))
# KeysView 繼承了mapping和set
print(2 in chains.keys())  # True
print(len(chains.keys()))  # 4(重復的不算)
# clear
chains.clear()
print(chains.maps)  # [{}, {1: 3, 3: 4, 4: 5}]

就像它的特點一樣,它適用於以下的情況:

  1. 多個字典;
  2. 允許key是重復;
  3. 總是訪問最高優先級字典中的關鍵字;
  4. 不需要改變key對應的value;
  5. 字典頻繁的創建和更新已經造成巨大的性能問題,希望改善性能問題;

Counter

這是一個繼承dict的子類,專門用來做計數器,dict中的方法這里同樣適用。

特有方法 解釋
init 初始化,參數為可迭代對象即可
elememts 返回一個生成器,其鍵值以無序的方式返回,並且只有值大於1的鍵值對才會返回
most_common 返回值最大的鍵值對,參數指定返回前多少個
subtract 減法,調用者的值發生改變
update 加法,調用者的值發生改變
[] 返回鍵對應的值,如果鍵不存在,那么返回0
+ 加法,返回一個新的counter對象,如果前面不存在,則默認加上一個對應鍵,值為0的counter
- 減法,返回一個新的counter對象,如果前面不存在,則默認用對應鍵,值為0的counter來減,其中值正數會變負數,負數變為正數
& min操作,取相對應的鍵的最小值,返回一個新的counter對象
max操作,取相對應的鍵的最大值,返回一個新的counter對象

其中數學運算如果其中一方的不存在,則會默認創建對應鍵,值為0的鍵值對。

from collections import Counter
# init
# 可迭代
counter = Counter("accab")  # Counter({'a': 2, 'c': 2, 'b': 1})
counter2 = Counter([1,2,3,4])  # Counter({1: 1, 2: 1, 3: 1, 4: 1})
counter5 = Counter([('a',3),('b', 2)])  # Counter({('a', 3): 1, ('b', 2): 1})
# 字典
counter3 = Counter({'a': 1, 'b': 2, 'a': 3})  # Counter({'a': 3, 'b': 2})
counter4 = Counter(a=1, b=2, c=1)  # Counter({'b': 2, 'a': 1, 'c': 1})
# elements
# 鍵值以無序的方式返回,並且只返回值大於等於1的鍵值對
elememts = counter.elements()
print([x for x in elememts])  # ['a', 'a', 'c', 'c', 'b']
# 為空是因為elements是generator
print(sorted(elememts))  # []
# most_common
# 鍵值以無序的方式返回
print(counter.most_common(1))  # [('a', 2)]
print(counter.most_common())  # [('a', 2), ('c', 2), ('b', 1)]
# update
# 單純是增加的功能,而不是像dict.update()中的替換一樣
counter.update("abb")
print(counter)  # Counter({'a': 3, 'b': 3, 'c': 2})
# subtract
counter.subtract(Counter("accc"))
print(counter)  # Counter({'b': 3, 'a': 2, 'c': -1})
print([x for x in counter.elements()])  # ['a', 'a', 'b', 'b', 'b']
# get
# 鍵不存在則返回0,但是不會加入到counter鍵值對中
print(counter['d'])
print(counter)  # Counter({'b': 3, 'a': 2, 'c': -1})
del counter['d']
# 還可以使用數學運算
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
# add two counters together:  c[x] + d[x]
print(c + d)  # Counter({'a': 4, 'b': 3})
# subtract (keeping only positive counts)
print(c - d)  # Counter({'a': 2})
# # intersection:  min(c[x], d[x])
print(c & d) # Counter({'a': 1, 'b': 1})
# union:  max(c[x], d[x])
print(c | d)  # Counter({'a': 3, 'b': 2})
# 一元加法和減法
c = Counter(a=3, b=-1)
# 只取正數
print(+c)  # Counter({'a': 3})
print(-c)  # Counter({'b': 1})

deque

由於deque同樣能夠提供列表相關的函數,所以其和列表相同的函數則不再贅述,這里比較獨特的是和left相關的函數以及rotate函數。

from collections import deque
# 從尾部進入,從頭部彈出,保證長度為5
dq1 = deque('abcdefg', maxlen=5)
print(dq1)  # ['c', 'd', 'e', 'f', 'g']
print(dq1.maxlen)  # 5
# 從左端入列
dq1.appendleft('q')
print(dq1)  # ['q', 'c', 'd', 'e', 'f']
# 從左端入列
dq1.extendleft('abc')
print(dq1)  # ['c', 'b', 'a', 'q', 'c']
# 從左端出列並且返回
dq1.popleft()  # c
print(dq1)  # ['b', 'a', 'q', 'c']
# 將隊頭n個元素進行右旋
dq1.rotate(2)
print(dq1)  # ['q', 'c', 'b', 'a']
# 將隊尾兩個元素進行左旋
dq1.rotate(-2)
print(dq1)  # ['b', 'a', 'q', 'c']
def tail(filename, n=10):
    'Return the last n lines of a file'
    with open(filename) as f:
        return deque(f, n)
def delete_nth(d, n):
    """
    實現隊列切片和刪除,pop之后再放會原處
    :param d: deque
    :param n: int
    :return:
    """
    d.roatte(-n)
    d.popleft()
    d.rotate(n)

OrderedDict

OrderedDict提供了一個有序字典,可以使用在遍歷的時候根據相應的順序進行輸出,因為在dict中它的item是以任意順序進行輸出的。

注意初始化的時候和在插入的話都根據插入順序進行排序,而不是根據key進行排序。

from collections import OrderedDict
items = {'c': 3, 'b': 2, 'a': 1}
regular_dict = dict(items)
ordered_dict = OrderedDict(items)
print(regular_dict)  # {'c': 3, 'b': 2, 'a': 1}
print(ordered_dict)  # [('c', 3), ('b', 2), ('a', 1)]
# 按照插入順序進行排序而不是
ordered_dict['f'] = 4
ordered_dict['e'] = 5
print(ordered_dict)  # [('c', 3), ('b', 2), ('a', 1), ('f', 4), ('e', 5)]
# 把最近加入的刪除
print(ordered_dict.popitem(last=True))  # ('e', 5)
# 按照加入的順序刪除
print(ordered_dict.popitem(last=False))  # ('c', 3)
print(ordered_dict)  # [('b', 2), ('a', 1), ('f', 4)]
# 移動到末尾
ordered_dict.move_to_end('b', last=True)
print(ordered_dict)  # [('a', 1), ('f', 4), ('b', 2)]
# 移動到開頭
ordered_dict.move_to_end('b', last=False)
print(ordered_dict)  # [('b', 2), ('a', 1), ('f', 4)]
ordered_dict['a'] = 3
# 說明更改值並不會影響加入順序
print(ordered_dict.popitem(last=True))  # ('f', 4)

提供了字典的功能,又保證了順序。

namedtuple

如果我們想要在tuple中使用名字的參數,而不是位置,namedtuple提供這么一個創建名稱tuple的機會。

from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, y=20)
print(p)  # Point(x=10, y=20)
print(p.x + p.y)  # 30


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM