1. 程式人生 > >Python高階資料結構之Collection

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)