Python高階資料結構之Collection
阿新 • • 發佈:2019-01-05
本章是Python高階資料結構的第一篇,由於之前沒有接觸過太多的Python版本的資料結構,所以在學習的過程中集百家之長和自己的見解,加以實踐,學習Python。 Python中用到tuple的方法,和注意事項都以程式碼的形式體現,高階之處在與其可以處理特殊場景的大部分資料描述問題。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-4-25 10:33
# @Author : coderManFans
# @Site : Python 高階資料結構模組
# 1.Python中的高階資料結構包括
# Collections,Array,Heapq,Bisect,Weakref,Copy,Pprint
# 2.Collections模組包含了內建型別之外的一些有用的工具,如Counter,defaultdict,OrderDict
# deque以及nametuple.其中Counter,deque以及defaultdict是最常用的類
#
# @File : collectionsDemo.py
# @Software: PyCharm
#1.Collections
#1.1 Counter()
'''
Counter繼承了dict類,其中seq為可迭代物件。接收seq,並以字典的形式返回seq
中每個元素(hashable)出現的次數
Counter的應用場景:
1.統計一個單詞在給定序列中一共出現了多少次
2.統計給定序列中不同單詞出現的次數
'''
from collections import Counter
list1 = ['a','b','c',23,23,'a','d','b','e']
counter1 = Counter(list1)
print(counter1)
print(counter1['a'])
#1.1.1統計不同單詞的數目
print(len(set(list1)))
#1.1.2對統計結果進行分組 下面的方法表示分為4組,不填預設全部分組,以列表
#儲存,裡面元素是tuple物件
print(counter1.most_common(4))
#1.1.3 elements()獲取Counter()生成物件的所有鍵名,重複的幾個會全部列印
# 該方法返回一個迭代器物件
keylist = counter1.elements()
print(keylist)
print(list(keylist))
#1.1.4 update(x) 更新計數器 把x的內容加入到原來計數器中
#x可以作為字串,列表,元組,集合,但是不能作為字典,純數字,否則報錯
list2 = ['a','d','f','q',2,3,2,3,4]
print(counter1)
counter1.update(list2)
print(counter1)
#1.1.5 substract(x) 更新計數器 把x代表的次數減少1,預設減少1,(通過字典形式指定一次減少的個數)
#,不存在則減為-1,依次減,作用與update()相反
counter1.subtract('a')
print(counter1)
counter1.subtract(['a','b',2])
print(counter1)
#1.2 Deque
'''
Deque是一種由佇列結構擴充套件而來的雙端佇列(double-ended queue),佇列元素
能夠在佇列兩端新增或者刪除。因此還被稱為頭尾連線列表(head-tail linked list),當然還有另一個特殊的資料結構也實現了這個
Deque 支援執行緒安全的,經過優化的append和pop操作,在佇列兩端的相關操作都能夠
達到近乎O(1)的時間複雜度。雖然list也支援類似的操作,但是它是
對定長列表的操作表現很不錯,而當遇到pop(0)和insert(o,v)
這樣既改變了列表的長度又改變其元素位置的操作時,其複雜度就變為O(n)了、
'''
from collections import deque
#1.2.1 定義一個雙向佇列(迴圈佇列)
de1 = deque()
#預設往雙向佇列右邊加入元素
de1.append('asdf')
print(de1)
#1.2.2 往雙向佇列左邊加入一個元素
de1.appendleft('2323')
de1.appendleft(232324)
de1.appendleft('2323')
de1.appendleft(23)
de1.appendleft(23)
print(de1)
#1.2.3 返回指定元素在雙向佇列中的個數
count1 = de1.count(23)
print(count1)
#1.2.4 反轉雙向佇列
print(de1)
de1.reverse()
print(de1)
#1.2.5 向雙向佇列中指定位置插入一個元素
de1.insert(2,'abced')
print(de1)
#1.2.6 用一個迭代器從右邊擴充套件雙向佇列,相當於從右邊批量插入
de1.extend(['a','adfasdf','asdf','asdfasd23'])
print(de1)
#1.2.7 用一個迭代器從左邊擴充套件雙向佇列,相當於從左邊批量插入
de1.extendleft(['2','3','2',22,';',23,233.002,23.22])
print(de1)
#1.2.8 返回從左到右遇到的第一個value的索引
index1 = de1.index('3')
print(index1)
#1.2.9 淺複製雙向佇列
de2 = de1.copy()
de3 = de2
de2.append('----asdfasdfa-sdf-asd-f')
print(de3)
print(de2)
#1.2.10 佇列的左旋轉,右旋轉
#預設向右旋轉n步(預設n = 1),n是負數則向左旋轉
print(de1)
de1.rotate(2)
print(de1)
#1.2.11 刪除並返回右邊的一個元素
val1 = de1.pop()
print(val1)
#1.2.12 刪除並返回左邊的一個元素
val2 = de1.popleft()
print(val2)
#1.2.13 刪除第一次出現的值
de1.remove('2')
print(de1)
#1.2.14 清空佇列中的資料
de1.clear()
print(de1)
#------------------------------------------------------------
#1.3 collections 中的 defaultDict
'''
該型別除了在處理不存在的鍵的操作之外與普通的字典完全相同。當查詢一個
不存在的鍵的操作發生時,它的default_factory會被呼叫,提供一個預設的值,
並且將這對鍵值儲存下來。其他的引數同普通的字典方法dict()一致,
一個defaultdict的例項同內建dict一樣擁有同樣的操作
defaultdict與dict唯一的區別就是初始化預設值的問題,
defaultdict的預設值可以是空list[],或者set{},或者0
defaultdict與dict.setdefault(key,[,default])是等價的,區別是複製的時候會被覆蓋
其他使用與dict沒有區別
defaultdict物件在當你希望使用它存放追蹤資料的時候很有用。
'''
from collections import defaultdict
list3 = [('yellow',1),('blue',2),('yellow',3),('blue',3)]
dict1 = defaultdict(list)
print(dict1)
for k,v in list3:
dict1[k].append(v)
print(dict1)
dict2 = defaultdict(set)
print(dict2)
dict3 = {}
#-----------------------------------------------------------------------------
#1.4 collections 有序字典 orderedDict的使用
'''
orderedDict是collections中的一個包,能夠記錄字典元素的插入順序,常常和排序函式一起使用
來生成一個排序的字典
預設的dict是不保證順序的,但是該類可以保證插入的順序
該物件裡的元素是字典物件,如果其順序不同,那麼則Python會認為是兩個不同的物件
'''
from collections import OrderedDict
dict4 = {'ba1':3,'aple':2,'pear':23,'orga':4}
#1.4.1 按照key排序
orderdict1 = OrderedDict(sorted(dict4.items(),key = lambda t:t[0]))
print(orderdict1)
#1.4.2 按照value排序
orderdict1 = OrderedDict(sorted(dict4.items(),key = lambda t:t[1]))
print(orderdict1)
dict5 = {'a':1,'c':2,'b':3}
dict6 = {'b':3,'a':1,'c':2}
print(dict5 == dict6)
#1.4.3 注意這種方式的初始化是保證順序的
orderdict2 = OrderedDict(dict5)
orderdict3 = OrderedDict(dict6)
print(orderdict2)
print(orderdict3)
print(orderdict3 == orderdict2)
orderdict4 = OrderedDict()
orderdict4['a'] = 123
orderdict4['b'] = 13
orderdict4['d'] = 1
orderdict5 = OrderedDict()
orderdict5['d'] = 1
orderdict5['b'] = 13
orderdict5['a'] = 123
print(orderdict4)
print(orderdict5)
print(orderdict4 == orderdict5)
#1.4.4 有序刪除 每次刪除最後一個,相當於記憶體的棧存放,後進先出,pop()是指定元素進行刪除
dict7 = orderdict5.popitem()
print(dict7)
orderdict5['h'] = 'asdfasdf'
orderdict5['e'] = 'asdfasdf'
#1.4.5 將指定鍵值移動到最後,也就是移動到最上面
print(orderdict5)
orderdict5.move_to_end('h')
print(orderdict5)
#1.4.6 設定預設鍵值
orderdict5.setdefault('k','is default value,key')
print(orderdict5)
#---------------------------------------------------------------------------
#1.5 namedtuple 可命名元組的使用方式
from collections import namedtuple
'''
namedtuple繼承tuple物件,namedtuple建立一個和tuple類似的物件,而且物件可以通過屬性名訪問元素值
tuple只通過索引去訪問,namedtuple可以提供基於物件的方式通過屬性名訪問元素值
每個元素都有自己的名字,類似於java的Bean,C語言中的struct。
同樣的,物件屬性一旦確定則不可更改,tuple中的值一旦確定也不可更改
但是在使用namedtuple的時候注意屬性名不能使用Python的關鍵字,如:class def等。
而且不能有重複的屬性名稱。
如果有屬性衝突的情況下,可以通過namedtuple開啟重新命名模式
'''
#1.5.1 初始化 下面的方式相當於建立了一個Person類 裡面有5個屬性
personObj = namedtuple("person",'name age gender address money ')
print(type(personObj))
print(personObj)
Bob = personObj(name='Bob',age=23,gender='nan',address='beijing',money=30000.00)
#上面的程式碼相當於建立了一個Person物件,下面則是通過元組的方式列印該Person物件
print(Bob)
zhangsan = personObj(name='zhangsan',age=40,gender='nan',address='nanjing',money=303330.00)
#通過屬性名之間訪問到屬性值
print(zhangsan.address+"-----"+zhangsan.gender+"----"+zhangsan.name)
#1.5.2 存在命名衝突的情況
#通過設定重新命名模式為True解決命名衝突的情況
personObj2 = namedtuple("person",'name age gender address money age ',rename=True)
#第二個衝突的屬性名通過: _+indexNum的方式表示,設定值的時候要通過 _+indexNum=value的方式
print(personObj2._fields)
lisi = personObj2(name='zhangsan',age=40,gender='nan',address='nanjing',money=303330.00,_5=30)
print(lisi)