py9 基礎類型擴展 collections模塊

CollectionsOverview

本文將從如下方面講述collections模塊對基礎類型的擴展
Alt text

tuple

Alt text
  1. tuple具備一個顯著的特性,不可變性,即元組內的內容不可變,可是元組的不可變性也不是絕對的。當元組內部存放可變元素,如列表時,則元組中的列表可變。
  2. 其次元組具備可迭代性是可迭代對象,能夠經過for-in進行迭代
  3. 此外元組還具備特別好用的拆包特性

元組的迭代與拆包

迭代
tuple_1 = ('weilianixn', 12345, 'cs', 18, 'male')
for i in tuple_1:
    print(i)
拆包
tuple_1 = ('weilianixn', 12345, 'cs', 18, 'male')
name, password, major,*part = tuple_1
print(name)
print(password)
print(part) # [18, 'male']
拆包時注意不要在for循環中進行拆包
for name, password, job, age, part in tuple_1:
ValueError: too many values to unpack (expected 5)

namedtuple

namedtuple是一個函數,返回一個繼承了tuple的簡易類,用屬性而不是索引來引用tuple的元素。用namedtuple生成的類很省空間,省去了class定義類的不少內置函數。而且用該類生成的對象還可拆包。主要研究_make和_asdict方法
# class User:
#     def __init__(self, name, password):
#         self.name = name
#         self.password = password
#
# user = User('wei', 1233214)
# print(user.password, user.name)  # 與下面等價

from collections import namedtuple

User_tuple = namedtuple('User_t', ['name', 'password', 'major', 'age'])
user_t = User_tuple(name='wei', password=2131, major='cs', age=18)

# tuple_1 = ('weilianixn', 12345, 'cs')
# user_t = User_tuple(*tuple_1, 18)  # *不加tuple_1會斷定成一個變量

# dict_1 = {
#     'name': 'wei',
#     'password': '123213',
#     'major': 'cs'
# }
# user_t = User_tuple(**dict_1, age=18)

print(user_t.name, user_t.password, user_t.major)
print(type(user_t))
  • _make方法
    make裏面傳遞一個可迭代對象,數量要與namedtuple生成的相符
    from collections import namedtuple
    
    User_tuple = namedtuple('User_t', ['name', 'password', 'major', 'age'])
    # list_1 = ['weilianixn', 12345, 'cs', 18]
    # dict_1 = {
    #     'name': 'wei',
    #     'password': '123213',
    #     'major': 'cs',
    #     'age': 18
    # }
    tuple_1 = ('weilianixn', 12345, 'cs', 18)
    
    user_t = User_tuple._make(tuple_1)
_make()方法和*的做用相似,至關於解析了括號內的可迭代對象,傳的是括號內的值
  • _ asdict方法
    將咱們的tuple轉換成字典
User_tuple = namedtuple('User_t', ['name', 'password', 'major','age'])
list_1 = ['weilianixn', 12345, 'cs',18]
user_t = User_tuple._make(list_1)
dict_12 = user_t._asdict()
print(dict_12)
# OrderedDict([('name', 'weilianixn'), ('password', 12345), ('major', 'cs'), ('age', 18)])

defaultdict

在說明defaultdict以前咱們先說一下普通dict使用時的缺陷,好比在作用戶數量統計時
user = ['wei1', 'wei2', 'wei1', 'wei3', 'wei2', 'wei3', 'wei1']
user_dict = {}
for i in user:
    if i in user_dict:
        user_dict[i] += 1
    else:
        user_dict[i] = 1
print(user_dict)
# {'wei1': 3, 'wei2': 2, 'wei3': 2}
上面方法能夠進行優化,把for循環優化以下,結果相同
for i in user:
    user_dict.setdefault(i, 0)
    user_dict[i] += 1
使用defaultdict來建立的話以下,defaultdict只接收可調用對象和none
from collections import defaultdict

user = ['wei1', 'wei2', 'wei1', 'wei3', 'wei2', 'wei3', 'wei1']
user_dict = defaultdict(int)
for i in user:
    user_dict[i] += 1
defaultdict傳list或int等就是直接把值初始化成空列表或者0等,若想傳有結構的字典或其餘自定義的結構採用如下方法
from collections import defaultdict

def group_d():
    return {
        'name': '',
        'nums': 0
    }
group_dict = {
    'group': {
        'name': '',
        'nums': 0
    }
}
user_dict = defaultdict(group_d)  # 不能傳group_dict,不但是可調用對象
user_dict['group']

deque

deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧:
>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
deque須要傳遞一個可迭代對象,傳遞字典時以字典的key生成一個列表
from collections import deque
deq = deque([1,2,3,4])
deq1 = deque({'name':'wei', 'age':18})
print(deq1)
# deque(['name', 'age'])
deque除了實現list的append()和pop()外,還支持appendleft()和popleft(),這樣就能夠很是高效地往頭部添加或刪除元素。
deque能夠限定隊列的長度,先入先出,能夠實現保留最後N個元素
下面是實現刪除文件的最後一行
from collections import deque

deq = deque(maxlen=5)
print(deq.__len__())
with open('02第二模塊之三體語錄', 'r+', encoding='utf-8') as f:
    with open('new', 'w', encoding='utf-8') as f1:
        while True:
            line = f.readline()
            if line:
                deq.append(line)
                if deq.__len__() == 5:
                    f1.write(deq[0])
            else:
                break
        for i in range(3):
            f1.write(deq[i + 1])

Counter

Counter是一個簡單的計數器,例如,統計字符出現的個數,是dict的一個子類,返回值是一個collections.Counter,相似於defaultdict,元素被儲存爲字典的keys,他們的計數被儲存爲字典的values
from collections import Counter

li = ['wei1', 'wei2', 'wei1', 'wei3', 'wei2', 'wei3', 'wei1']
counter = Counter(li)
# Counter({'name': 'wei', 'age': 18})


c = Counter()
for ch in 'programming':
    c[ch] = c[ch] + 1  # 只有defaultdict才能這樣用
print(c)
# Counter({'r': 2, 'g': 2, 'm': 2, 'p': 1, 'o': 1, 'a': 1, 'i': 1, 'n': 1})
  • Count.update()
    能夠在原統計的基礎上更進一步統計,可接受可迭代對象,也可接受另外一個count對象,該方法是在原函數上進行修改,返回值爲none
  • Count.most_common()
    接收數字參數,統計出現前幾多的元素
  • elements()
    相似於字典中的keys()方法
  • values()
    相似於字典中的vaues()方法
  • update()
    相似於字典中的update()方法對計數器進行更新
  • substract()
    對計數器進行反向計數
from collections import Counter
c = Counter('which')
c.subtract('witch')
# Counter({'c': 0, 'h': 1, 'i': 0, 't': -1, 'w': 0})
c.subtract('witch')
# Counter({'c': -1, 'h': 0, 'i': -1, 't': -2, 'w': -1})

OrderedDict

能夠實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最先添加的Key。
  • move_to_end()
    能夠吧一個鍵值對調到最後
  • popitem()
    默認把排在最後的一個鍵值對刪除
  • pop(key)
    根據傳入的key把相應的鍵值對刪除並返回value

ChainMap

ChainMap可以將多個dict聯合起來進行操做
from collections import ChainMap

dict1 = {'a': "w1", 'b': 'w2', 'c': 'w3'}
dict2 = {'c': 'w2', 'd': 'w4', 'e': 'w5'}
new_dict = ChainMap(dict1, dict2)
dict1['a'] = 'w'
print(new_dict)
for item in new_dict.items():
    print(item)
print(new_dict.maps)
結果爲
ChainMap({‘a’: ‘w’, ‘b’: ‘w2’, ‘c’: ‘w3’}, {‘c’: ‘w2’, ‘d’: ‘w4’, ‘e’: ‘w5’})
(‘c’, ‘w3’)
(‘d’, ‘w4’)
(‘e’, ‘w5’)
(‘a’, ‘w’)
(‘b’, ‘w2’)
[{‘a’: ‘w’, ‘b’: ‘w2’, ‘c’: ‘w3’}, {‘c’: ‘w2’, ‘d’: ‘w4’, ‘e’: ‘w5’}]
  • new_child()
    至關於update,對原數據進行更新。
  • parents()
    根據原ChainMap進行[1:]切片,返回一個新的ChainMap
相關文章
相關標籤/搜索