Python高級數據結構之Collection

本章是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)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章