欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中collections模塊的基本使用教程

 更新時間:2018年12月07日 11:20:21   作者:廖高祥  
collections是Python內(nèi)建的一個集合模塊,提供了許多有用的集合類。下面這篇文章主要給大家介紹了關(guān)于Python中collections模塊的基本使用,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

之前認(rèn)識了python基本的數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu),現(xiàn)在認(rèn)識一個高級的:Collections,一個模塊主要用來干嘛,有哪些類可以使用,看__init__.py就知道

'''This module implements specialized container datatypes providing
alternatives to Python's general purpose built-in containers, dict,
list, set, and tuple.

* namedtuple   factory function for creating tuple subclasses with named fields
* deque        list-like container with fast appends and pops on either end
* ChainMap     dict-like class for creating a single view of multiple mappings
* Counter      dict subclass for counting hashable objects
* OrderedDict  dict subclass that remembers the order entries were added
* defaultdict  dict subclass that calls a factory function to supply missing values
* UserDict     wrapper around dictionary objects for easier dict subclassing
* UserList     wrapper around list objects for easier list subclassing
* UserString   wrapper around string objects for easier string subclassing

'''

__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
            'UserString', 'Counter', 'OrderedDict', 'ChainMap']

collections模塊實現(xiàn)一些特定的數(shù)據(jù)類型,可以替代Python中常用的內(nèi)置數(shù)據(jù)類型如dict, list, set, tuple,簡單說就是對基本數(shù)據(jù)類型做了更上一層的處理。

一、deque

用途:雙端隊列,頭部和尾部都能以O(shè)(1)時間復(fù)雜度插入和刪除元素。類似于列表的容器

所謂雙端隊列,就是兩端都能操作,與Python內(nèi)置的list區(qū)別在于:頭部插入與刪除的時間復(fù)雜度為O(1),來個栗子感受一下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

"""
保留最后n個元素
"""
from collections import deque


def search(file, pattern, history=5):
 previous_lines = deque(maxlen=history)
 for l in file:
 if pattern in l:
  yield l, previous_lines # 使用yield表達(dá)式的生成器函數(shù),將搜索過程的代碼和搜索結(jié)果的代碼解耦
 previous_lines.append(l)


with open(b'file.txt', mode='r', encoding='utf-8') as f:
 for line, prevlines in search(f, 'Python', 5):
 for pline in prevlines:
  print(pline, end='')
 print(line, end='')

d = deque()
d.append(1)
d.append("2")
print(len(d))
print(d[0], d[1])
d.extendleft([0])
print(d)
d.extend([6, 7, 8])
print(d)

d2 = deque('12345')
print(len(d2))
d2.popleft()
print(d2)
d2.pop()
print(d2)

# 在隊列兩端插入或刪除元素時間復(fù)雜度都是 O(1) ,區(qū)別于列表,在列表的開頭插入或刪除元素的時間復(fù)雜度為 O(N)
d3 = deque(maxlen=2)
d3.append(1)
d3.append(2)
print(d3)
d3.append(3)
print(d3)

輸出結(jié)果如下

人生苦短
我用Python
2
1 2
deque([0, 1, '2'])
deque([0, 1, '2', 6, 7, 8])
5
deque(['2', '3', '4', '5'])
deque(['2', '3', '4'])
deque([1, 2], maxlen=2)
deque([2, 3], maxlen=2)

因此,如果你遇到經(jīng)常操作列表頭的場景,使用deque最好。deque類的所有方法,自行操作一遍就知道了。

class deque(object):
 """
 deque([iterable[, maxlen]]) --> deque object
 
 A list-like sequence optimized for data accesses near its endpoints.
 """
 def append(self, *args, **kwargs): # real signature unknown
 """ Add an element to the right side of the deque. """
 pass

 def appendleft(self, *args, **kwargs): # real signature unknown
 """ Add an element to the left side of the deque. """
 pass

 def clear(self, *args, **kwargs): # real signature unknown
 """ Remove all elements from the deque. """
 pass

 def copy(self, *args, **kwargs): # real signature unknown
 """ Return a shallow copy of a deque. """
 pass

 def count(self, value): # real signature unknown; restored from __doc__
 """ D.count(value) -> integer -- return number of occurrences of value """
 return 0

 def extend(self, *args, **kwargs): # real signature unknown
 """ Extend the right side of the deque with elements from the iterable """
 pass

 def extendleft(self, *args, **kwargs): # real signature unknown
 """ Extend the left side of the deque with elements from the iterable """
 pass

 def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__
 """
 D.index(value, [start, [stop]]) -> integer -- return first index of value.
 Raises ValueError if the value is not present.
 """
 return 0

 def insert(self, index, p_object): # real signature unknown; restored from __doc__
 """ D.insert(index, object) -- insert object before index """
 pass

 def pop(self, *args, **kwargs): # real signature unknown
 """ Remove and return the rightmost element. """
 pass

 def popleft(self, *args, **kwargs): # real signature unknown
 """ Remove and return the leftmost element. """
 pass

 def remove(self, value): # real signature unknown; restored from __doc__
 """ D.remove(value) -- remove first occurrence of value. """
 pass

 def reverse(self): # real signature unknown; restored from __doc__
 """ D.reverse() -- reverse *IN PLACE* """
 pass

 def rotate(self, *args, **kwargs): # real signature unknown
 """ Rotate the deque n steps to the right (default n=1). If n is negative, rotates left. """
 pass

這里提示一下,有些函數(shù)對隊列進(jìn)行操作,但返回值是None,比如reverse()反轉(zhuǎn)隊列,rotate(1)將隊列中元素向右移1位,尾部的元素移到頭部。

二、defaultdict

用途:帶有默認(rèn)值的字典。父類為Python內(nèi)置的dict

字典帶默認(rèn)值有啥好處?舉個栗子,一般來講,創(chuàng)建一個多值映射字典是很簡單的。但是,如果你選擇自己實現(xiàn)的話, 那么對于值的初始化可能會有點麻煩,你可能會像下面這樣來實現(xiàn):

d = {}
for key, value in pairs:
 if key not in d:
 d[key] = []
 d[key].append(value)

如果使用 defaultdict 的話代碼就更加簡潔了:

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

defaultdict 的一個特征是它會自動初始化每個 key 剛開始對應(yīng)的值,所以你只需要 關(guān)注添加元素操作了。比如:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

# 字典中的鍵映射多個值
from collections import defaultdict

d = defaultdict(list)
print(d)
d['a'].append([1, 2, 3])
d['b'].append(2)
d['c'].append(3)

print(d)

d = defaultdict(set)
print(d)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)

print(d)

輸出結(jié)果如下:

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

三、namedtuple()

用途:創(chuàng)建命名字段的元組。工廠函數(shù)

namedtuple主要用來產(chǎn)生可以使用名稱來訪問元素的數(shù)據(jù)對象,通常用來增強代碼的可讀性, 在訪問一些tuple類型的數(shù)據(jù)時尤其好用。

比如我們用戶擁有一個這樣的數(shù)據(jù)結(jié)構(gòu),每一個對象是擁有三個元素的tuple。使用namedtuple方法就可以方便的通過tuple來生成可讀性更高也更好用的數(shù)據(jù)結(jié)構(gòu)。

from collections import namedtuple

websites = [
 ('Sohu', 'http://www.sohu.com/', u'張朝陽'),
 ('Sina', 'http://www.sina.com.cn/', u'王志東'),
 ('163', 'http://www.163.com/', u'丁磊')
]

Website = namedtuple('Website', ['name', 'url', 'founder'])

for website in websites:
 website = Website._make(website)
 print website


# 輸出結(jié)果:
Website(name='Sohu', url='http://www.sohu.com/', founder=u'\u5f20\u671d\u9633')
Website(name='Sina', url='http://www.sina.com.cn/', founder=u'\u738b\u5fd7\u4e1c')
Website(name='163', url='http://www.163.com/', founder=u'\u4e01\u78ca')

注意,namedtuple是函數(shù),不是類。

四、Counter

用途:統(tǒng)計可哈希的對象。父類為Python內(nèi)置的dict

尋找序列中出現(xiàn)次數(shù)最多的元素。假設(shè)你有一個單詞列表并且想找出哪個單詞出現(xiàn)頻率最高:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

from collections import Counter

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'
]

word_counts = Counter(words)

# 出現(xiàn)頻率最高的三個單詞
top_three = word_counts.most_common(3)
print(top_three)
# Outputs [('eyes', 8), ('the', 5), ('look', 4)]
print(word_counts['eyes'])

morewords = ['why', 'are', 'you', 'not', 'looking', 'in', 'my', 'eyes']

# 如果你想手動增加計數(shù),可以簡單的用加法:
for word in morewords:
 print(word)
 word_counts[word] += 1
print(word_counts['eyes'])

結(jié)果如下:

[('eyes', 8), ('the', 5), ('look', 4)]
8
why
are
you
not
looking
in
my
eyes
9

因為Counter繼承自dict,所有dict有的方法它都有(defaultdict和OrderedDict也是的),Counter自己實現(xiàn)或重寫了6個方法:

  • most_common(self, n=None),
  • elements(self)
  • fromkeys(cls, iterable, v=None)
  • update(*args, **kwds)
  • subtract(*args, **kwds)
  • copy(self)

五、OrderedDict

用途:排序的字段。父類為Python內(nèi)置的dict

OrderedDict在迭代操作的時候會保持元素被插入時的順序,OrderedDict內(nèi)部維護(hù)著一個根據(jù)鍵插入順序排序的雙向鏈表。每次當(dāng)一個新的元素插入進(jìn)來的時候,它會被放到鏈表的尾部。對于一個已經(jīng)存在的鍵的重復(fù)賦值不會改變鍵的順序。

需要注意的是,一個OrderedDict的大小是一個普通字典的兩倍,因為它內(nèi)部維護(hù)著另外一個鏈表。 所以如果你要構(gòu)建一個需要大量OrderedDict 實例的數(shù)據(jù)結(jié)構(gòu)的時候(比如讀取100,000行CSV數(shù)據(jù)到一個 OrderedDict 列表中去),那么你就得仔細(xì)權(quán)衡一下是否使用 OrderedDict帶來的好處要大過額外內(nèi)存消耗的影響。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

from collections import OrderedDict

d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# d['bar'] = 22 #對于一個已經(jīng)存在的鍵,重復(fù)賦值不會改變鍵的順序
for key in d:
 print(key, d[key])

print(d)

import json

print(json.dumps(d))

結(jié)果如下:

  • foo 1
  • bar 2
  • spam 3
  • grok 4
  • OrderedDict([('foo', 1), ('bar', 2), ('spam', 3), ('grok', 4)])
  • {"foo": 1, "bar": 2, "spam": 3, "grok": 4}

OrderDict實現(xiàn)或重寫了如下方法。都是干嘛的?這個留給大家當(dāng)課后作業(yè)了^_^

  • clear(self)
  • popitem(self, last=True)
  • move_to_end(self, key, last=True)
  • keys(self)
  • items(self)
  • values(self)
  • pop(self, key, default=__marker)
  • setdefault(self, key, default=None)
  • copy(self)
  • fromkeys(cls, iterable, value=None)

六、ChainMap

用途:創(chuàng)建多個可迭代對象的集合。類字典類型

很簡單,如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

from collections import ChainMap
from itertools import chain

# 不同集合上元素的迭代
a = [1, 2, 3, 4]
b = ('x', 'y', 'z')
c = {1, 'a'}

# 方法一,使用chain
for i in chain(a, b, c):
 print(i)
print('--------------')
# 方法二,使用chainmap
for j in ChainMap(a, b, c):
 print(j)

# 這兩種均為節(jié)省內(nèi)存,效率更高的迭代方式

一個 ChainMap 接受多個字典并將它們在邏輯上變?yōu)橐粋€字典。然后,這些字典并不是真的合并在一起了,ChainMap 類只是在內(nèi)部創(chuàng)建了一個容納這些字典的列表并重新定義了一些常見的字典操作來遍歷這個列表。大部分字典操作都是可以正常使用的,比如:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = 'liao gao xiang'

# 合并多個字典和映射
a = {'x': 1, 'z': 3}
b = {'y': 2, 'z': 4}
# 現(xiàn)在假設(shè)你必須在兩個字典中執(zhí)行查找操作
# (比如先從 a 中找,如果找不到再在 b 中找)。
# 一個非常簡單的解決方案就是使用collections模塊中的ChainMap類
from collections import ChainMap

c = ChainMap(a, b)

print(c)
a['x'] = 11 # 使用ChainMap時,原字典做了更新,這種更新會合并到新的字典中去

print(c) # 按順序合并兩個字典
print(c['x'])
print(c['y'])
print(c['z'])

# 對于字典的更新或刪除操作影響的總是列中的第一個字典。
c['z'] = 10
c['w'] = 40
del c['x']
print(a)
# del c['y']將出現(xiàn)報錯

# ChainMap對于編程語言中的作用范圍變量(比如globals,locals等)
# 是非常有用的。事實上,有一些方法可以使它變得簡單:
values = ChainMap() # 默認(rèn)會創(chuàng)建一個空字典
print('\t', values)
values['x'] = 1
values = values.new_child() # 添加一個空字典
values['x'] = 2
values = values.new_child()
values['x'] = 30
# values = values.new_child()
print(values, values['x']) # values['x']輸出最后一次添加的值
values = values.parents # 刪除上一次添加的字典
print(values['x'])
values = values.parents
print(values)

a = {'x': 1, 'y': 2}
b = {'y': 2, 'z': 3}
merge = dict(b)
merge.update(a)
print(merge['x'], merge['y'], merge['z'])
a['x'] = 11
print(merge['x'])

輸出結(jié)果如下:

ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
ChainMap({'x': 11, 'z': 3}, {'y': 2, 'z': 4})
11
2
3
{'z': 10, 'w': 40}
     ChainMap({})
ChainMap({'x': 30}, {'x': 2}, {'x': 1}) 30
2
ChainMap({'x': 1})
1 2 3
1

作為ChainMap的替代,你可能會考慮使用 update() 方法將兩個字典合并。這樣也能行得通,但是它需要你創(chuàng)建一個完全不同的字典對象(或者是破壞現(xiàn)有字典結(jié)構(gòu))。同時,如果原字典做了更新,這種改變不會反應(yīng)到新的合并字典中去。

ChainMap實現(xiàn)或重寫了如下方法:

  • get(self, key, default=None)
  • fromkeys(cls, iterable, *args)
  • copy(self)
  • new_child(self, m=None)
  • parents(self)
  • popitem(self)
  • pop(self, key, *args)
  • clear(self)

七、UserDict、UserList、UserString

這三個類是分別對 dict、list、str 三種數(shù)據(jù)類型的包裝,其主要是為方便用戶實現(xiàn)自己的數(shù)據(jù)類型。在 Python2 之前,這三個類分別位于 UserDict、UserList、UserString 三個模塊中,需要用類似于 from UserDict import UserDict 的方式導(dǎo)入。在 Python3 之后則被挪到了 collections 模塊中。這三個類都是基類,如果用戶要擴(kuò)展這三種類型,只需繼承這三個類即可。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Python實現(xiàn)視頻畫質(zhì)增強的示例代碼

    Python實現(xiàn)視頻畫質(zhì)增強的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Python語言實現(xiàn)對視頻進(jìn)行畫質(zhì)增強功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-04-04
  • 一文帶你玩轉(zhuǎn)python中的requests函數(shù)

    一文帶你玩轉(zhuǎn)python中的requests函數(shù)

    在Python中,requests庫是用于發(fā)送HTTP請求的常用庫,因為它提供了簡潔易用的接口,本文將深入探討requests庫的使用方法,感興趣的可以學(xué)習(xí)下
    2023-08-08
  • python圖形繪制奧運五環(huán)實例講解

    python圖形繪制奧運五環(huán)實例講解

    在本文里我們給大家整理了一篇關(guān)于python圖形繪制奧運五環(huán)的實例內(nèi)容,大家可以跟著學(xué)習(xí)下。
    2019-09-09
  • Python去除字符串前后空格的三種方法匯總

    Python去除字符串前后空格的三種方法匯總

    這篇文章主要給大家介紹了關(guān)于Python去除字符串前后空格的三種方法,需要的朋友可以參考下
    2023-01-01
  • Python操作Excel把數(shù)據(jù)分給sheet

    Python操作Excel把數(shù)據(jù)分給sheet

    這篇文章主要介紹了Python操作Excel把數(shù)據(jù)分給sheet,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • python3 QT5 端口轉(zhuǎn)發(fā)工具兩種場景分析

    python3 QT5 端口轉(zhuǎn)發(fā)工具兩種場景分析

    這篇文章主要介紹了python3 QT5 端口轉(zhuǎn)發(fā)工具,功能是打開本機(jī)端口,映射到指定IP的端口,接下來通過兩種場景給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2022-01-01
  • Python虛擬環(huán)境venv用法詳解

    Python虛擬環(huán)境venv用法詳解

    這篇文章主要介紹了Python虛擬環(huán)境venv用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • Python多線程中線程數(shù)量如何控制

    Python多線程中線程數(shù)量如何控制

    本文主要介紹了Python多線程中線程數(shù)量如何控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • sklearn中make_blobs的用法詳情

    sklearn中make_blobs的用法詳情

    這篇文章主要介紹了sklearn中make_blobs的用法詳情,sklearn中的make_blobs函數(shù)主要是為了生成數(shù)據(jù)集的,下面文章的學(xué)習(xí)內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01
  • 解決django.db.utils.IntegrityError:(1048, Column last_login cannot be null)

    解決django.db.utils.IntegrityError:(1048, Column las

    這篇文章主要介紹了解決django.db.utils.IntegrityError:(1048, Column last_login cannot be null)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論