python常見的數據結構


Python中常見的數據結構可以統稱為容器。序列(如列表和元組)、映射(如字典)以及集合(set)是三類主要的容器。

線性數據結構分類:棧(stack)--先進后出、 隊列(queue)-先進先出、雙端隊列(deque)、鏈表(LinkedList)

一、序列(列表、元組和字符串)

序列中的每個元素都有自己的編號。Python中有6種內建的序列。其中列表和元組是最常見的類型。其他包括字符串、Unicode字符串、buffer對象和xrange對象。下面重點介紹下列表、元組和字符串。

1、列表

列表是可變的,這是它區別於字符串和元組的最重要的特點,一句話概括即:列表可以修改,而字符串和元組不能。

可變數據類型
    列表、字典、集合         不可哈希
    集合里存的元素必須是不可變的數據類型,無序,不重復(去重)

不可變數據類型
    元組、數字、字符串       可哈希
可變數據類型和不可變數據類型

(1) 列表操作包含以下函數

cmp(list1, list2):比較兩個列表的元素
len(list):列表元素個數
max(list):返回列表元素最大值
min(list):返回列表元素最小值
list(seq):將元組轉換為列表

(2) 列表操作包含以下方法

list.append(obj):在列表末尾添加新的對象
list.count(obj):統計某個元素在列表中出現的次數
list.extend(seq):在列表末尾一次性追加另一個序列中的多個值(用新列表擴展原來的列表)
list.index(obj):從列表中找出某個值第一個匹配項的索引位置
list.insert(index, obj):將對象插入列表
list.pop(obj=list[-1]):移除列表中的一個元素(默認最后一個元素),並且返回該元素的值
list.remove(obj):移除列表中某個值的第一個匹配項
list.reverse():反向列表中元素
list.sort([func]):對原列表進行排序

(3) copy()與deepcopy()的區別

對於不可變的對象來說(數字,字符串,元組),深淺拷貝沒有區別
深復制,即將被復制對象完全再復制一遍作為獨立的新個體單獨存在。所以改變原有被復制對象不會對已經復制出來的新對象產生影響。
等於賦值,並不會產生一個獨立的對象單獨存在,他只是將原有的數據塊打上一個新標簽,所以當其中一個標簽被改變的時候,數據塊就會發生變化,另一個標簽也會隨之改變。
淺復制要分兩種情況進行討論:
1)當淺復制的值是不可變對象(數值,字符串,元組)時和“等於賦值”的情況一樣,對象的id值與淺復制原來的值相同。
2)當淺復制的值是可變對象(列表和元組)時會產生一個“不是那么獨立的對象”存在。有兩種情況:
第一種情況:復制的對象中無復雜子對象,原來值的改變並不會影響淺復制的值,同時淺復制的值改變也並不會影響原來的值。
原來值的id值與淺復制原來的值不同。
第二種情況:復制的對象中有 復雜 子對象 (例如列表中的一個子元素是一個列表),如果不改變其中復雜子對象,
淺復制的值改變並不會影響原來的值。 但是改變原來的值 中的復雜子對象的值 會影響淺復制的值。

2、元組

Python的元組與列表類似,不同之處在於元組的元素不能修改。元組使用小括號,列表使用方括號。元組創建很簡單,只需要在括號中添加元素,並使用逗號隔開即可。

(1) 元組操作包含以下函數

cmp(list1, list2):比較兩個元組的元素
len(list):元組元素個數
max(list):返回元組元素最大值
min(list):返回元組元素最小值
tuple(seq):將列表轉換為元組

(2) 修改元組

元組中的元素值是不允許修改的,但我們可以對元組進行連接組合,如下實例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
 
# 以下修改元組元素操作是非法的。
# tup1[0] = 100
 
# 創建一個新的元組
tup3 = tup1 + tup2
print(tup3)

(3) 刪除元組

元組中的元素值是不允許刪除的,但我們可以使用del語句來刪除整個元組

注意:只含一個值的元組,必須加個逗號(,);

3、字符串

字符串是 Python 中最常用的數據類型。我們可以使用引號('或")來創建字符串。創建字符串很簡單,只要為變量分配一個值即可

'strs'.capitalize()        #首字母大寫
'strs'.title()             #每個單詞首字母大寫
'strs'.upper()             #每個字母變為大寫
'strs'.lower()             #每個字母變為小寫
'strs'.swapcase()          #大小寫互換
'strs'.count()             #計算指定字符串或字符出現的次數
'strs'.find()              #根據指定的字符獲取該字符在字符串中第一次出現的索引位置(找不到索引返回-1)
'strs'.index()             #根據指定的字符獲取該字符在字符串中第一次出現的索引位置(找不到索引返回一個異常錯誤)
'strs'.startswith()        #檢測字符串是否以指定字符開頭
'strs'.endswith()          #檢測字符串是否以指定字符結尾
'strs'.isupper()           #檢測字符串是否都為大寫字母
'strs'.islower()           #檢測字符串是否都為小寫字母
'strs'.istitle()           #檢測字符串是否都為單詞首字母大寫
'strs'.isalnum()           #檢測字符串是否只由字母和數字字符組成
'strs'.isalpha()           #檢測字符串是否只由字母字符(含中文字符)組成
'strs'.isdigit()           #檢測字符串是否只由十進制數字字符組成
'strs'.isnumeric()         #檢測字符串是否以數字字符組成
'strs'.isdecimal()         #檢測字符串是否以數字字符組成
'strs'.isspace()           #檢測字符串是否由空白字符組成
'strs'.split()             #使用指定字符,將字符串進行切割並裝入列表
'strs'.splitlines()        #使用回車字符,切割字符串並裝入列表中
'strs'.join(['a','b','c']) #將容器中的字符串使用指定字符拼接成一個字符串
'strs'.zfill()             #使用0填充字符串,參數為填充后的總位數
'strs'.center()            #用指定字符,將字符串居中填充到指定長度,參數(長度,使用的字符)
'strs'.ljust()             #用指定字符,將字符串左對齊填充到指定長度,參數(長度,使用的字符)
'strs'.rjust()             #用指定字符,將字符串右對齊填充到指定長度,參數(長度,使用的字符)
'strs'.strip()             #去掉字符串中,兩側指定重復的字符(如果不指定字符,則刪除空格)
'strs'.lstrip()            #去掉字符串中,左側指定重復的字符(如果不指定字符,則刪除空格)
'strs'.rjust()             #去掉字符串中,右側指定重復的字符(如果不指定字符,則刪除空格)
#替換字符串中的字符
'strs'.maketrans()         #制作字典
'strs'.translate()         #使用字典替換
#exampel
var = 'wiz good guy,wiz super cool'
flag = ''.maketrans('wiz','wwr')
res = var.translate(flag)
字符串內建函數

(1) Python字符串格式化--format()方法

1.簡單運用

字符串類型格式化采用format()方法,基本使用格式是:

     <模板字符串>.format(<逗號分隔的參數>)

調用format()方法后會返回一個新的字符串,參數從0 開始編號。

"{}:計算機{}的CPU 占用率為{}%。".format("2016-12-31","PYTHON",10)
Out[10]: '2016-12-31:計算機PYTHON的CPU 占用率為10%。'

format()方法可以非常方便地連接不同類型的變量或內容,如果需要輸出大括號,采用{{表示{,}}表示},例如:

1.  "{}{}{}".format("圓周率是",3.1415926,"...")
2.  Out[11]: '圓周率是3.1415926...'
3.  "圓周率{{{1}{2}}}是{0}".format("無理數",3.1415926,"...")
4.  Out[12]: '圓周率{3.1415926...}是無理數'
5.  s="圓周率{{{1}{2}}}是{0}" #大括號本身是字符串的一部分
6.  s
7.  Out[14]: '圓周率{{{1}{2}}}是{0}'
8.  s.format("無理數",3.1415926,"...") #當調用format()時解析大括號
9.  Out[15]: '圓周率{3.1415926...}是無理數'
2. 格式控制信息

   format()方法中<模板字符串>的槽除了包括參數序號,還可以包括格式控制信息。此時,槽的內部樣式如下:

     {<參數序號>: <格式控制標記>}

     其中,<格式控制標記>用來控制參數顯示時的格式,包括:<填充><對齊><寬度>,<.精度><類型>6 個字段,這些字段都是可選的,可以組合使用,逐一介紹如下。

<寬度>

指當前槽的設定輸出字符寬度,如果該槽對應的format()參數長度比<寬度>設定值大,則使用參數實際長度。如果該值的實際位數小於指定寬度,則位數將被默認以空格字符補充。

<對齊>

指參數在<寬度>內輸出時的對齊方式,分別使用<、>和^三個符號表示左對齊、右對齊和居中對齊。

<填充>

指<寬度>內除了參數外的字符采用什么方式表示,默認采用空格,可以通過<填充>更換。

1.  s = "PYTHON"
2.  "{0:30}".format(s)
3.  Out[17]: 'PYTHON                        '
4.  "{0:>30}".format(s)
5.  Out[18]: '                        PYTHON'
6.  "{0:*^30}".format(s)
7.  Out[19]: '************PYTHON************'
8.  "{0:-^30}".format(s)
9.  Out[20]: '------------PYTHON------------'
10."{0:3}".format(s)
11.Out[21]: 'PYTHON'

逗號(,)

<格式控制標記>中逗號(,)用於顯示數字的千位分隔符,例如:

1.  "{0:-^20,}".format(1234567890)
2.  Out[24]: '---1,234,567,890----'
3.  "{0:-^20}".format(1234567890) #對比輸出
4.  Out[25]: '-----1234567890-----'
5.  "{0:-^20,}".format(12345.67890)
6.  Out[26]: '----12,345.6789-----'

 <.精度>

表示兩個含義,由小數點(.)開頭。對於浮點數,精度表示小數部分輸出的有效位數。對於字符串,精度表示輸出的最大長度。

1.  "{0:.2f}".format(12345.67890)
2.  Out[29]: '12345.68'
3.  "{0:H^20.3f}".format(12345.67890)
4.  Out[30]: 'HHHHH12345.679HHHHHH'
5.  "{0:.4}".format("PYTHON")
6.  Out[31]: 'PYTH'

 <類型>

表示輸出整數和浮點數類型的格式規則。對於整數類型,輸出格式包括6 種:

  • b: 輸出整數的二進制方式;
  • c: 輸出整數對應的 Unicode 字符;
  • d: 輸出整數的十進制方式;
  • o: 輸出整數的八進制方式;
  • x: 輸出整數的小寫十六進制方式;
  • X: 輸出整數的大寫十六進制方式;
1.  "{0:b},{0:c},{0:d},{0:o},{0:x},{0:X}".format(425)
2.  Out[32]: '110101001,Ʃ,425,651,1a9,1A9'

對於浮點數類型,輸出格式包括4 種:

  • e: 輸出浮點數對應的小寫字母 e 的指數形式;
  • E: 輸出浮點數對應的大寫字母 E 的指數形式;
  • f: 輸出浮點數的標准浮點形式;
  • %: 輸出浮點數的百分形式。

     浮點數輸出時盡量使用<.精度>表示小數部分的寬度,有助於更好控制輸出格式。

1.  "{0:e},{0:E},{0:f},{0:%}".format(3.14)
2.  Out[33]: '3.140000e+00,3.140000E+00,3.140000,314.000000%'
3.  "{0:.2e},{0:.2E},{0:.2f},{0:.2%}".format(3.14)
4.  Out[34]: '3.14e+00,3.14E+00,3.14,314.00%'

4、通用序列操作(方法)

從列表、元組以及字符串可以“抽象”出序列的一些公共通用方法(不是你想像中的CRUD),這些操作包括:索引(indexing)、分片(sliceing)、加(adding)、乘(multiplying)以及檢查某個元素是否屬於序列的成員。除此之外,還有計算序列長度、最大最小元素等內置函數。

(1)索引

str1='Hello'
nums=[1,2,3,4]
t1=(123,234,345)
print (str1[0])
print (nums[1])
print (t1[2])

輸出

H
2
345

索引從0(從左向右)開始,所有序列可通過這種方式進行索引。神奇的是,索引可以從最后一個位置(從右向左)開始,編號是-1:

str1='Hello'
nums=[1,2,3,4]
t1=(123,234,345)
print (str1[-1])
print (nums[-2])
print (t1[-3])

輸出:

o
3
123

(2)分片

分片操作用來訪問一定范圍內的元素。分片通過冒號相隔的兩個索引來實現:

nums=range(10)
print (nums)
print (nums[1:5])
print (nums[6:10])
print (nums[1:])
print (nums[-3:-1])
print (nums[-3:]) #包括序列結尾的元素,置空最后一個索引
print (nums[:]) #復制整個序列

輸出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4]
[6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[7, 8]
[7, 8, 9]

不同的步長,有不同的輸出:

nums=range(10)
print (nums)
print (nums[0:10])  #默認步長為1 等價於nums[1:5:1]
print (nums[0:10:2]) #步長為2
print (nums[0:10:3])  #步長為3
 
##print (nums[0:10:0])  #步長為0
print (nums[0:10:-2])  #步長為-2

輸出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8]
[0, 3, 6, 9]
[]

(3)序列相加

str1='Hello'
str2=' world'
print (str1+str2)
num1=[1,2,3]
num2=[2,3,4]
print (num1+num2)
print (str1+num1)

輸出:

Hello world
[1, 2, 3, 2, 3, 4]

Traceback (most recent call last):
  File "F:\Python\test.py", line 7, in <module>
    print str1+num1
TypeError: cannot concatenate 'str' and 'list' objects

(4)乘法

print [None]*10
str1='Hello'
print (str1*2)
num1=[1,2]
print (num1*2)
print (str1*num1)

輸出:

[None, None, None, None, None, None, None, None, None, None]

HelloHello
[1, 2, 1, 2]

Traceback (most recent call last):
  File "F:\Python\test.py", line 5, in <module>
    print str1*num1
TypeError: can't multiply sequence by non-int of type 'list'

(5)成員資格

in運算符會用來檢查一個對象是否為某個序列(或者其他類型)的成員(即元素):

str1='Hello'
print ('h' in str1)
print ('H' in str1)
num1=[1,2]
print (1 in num1)

輸出:

False
True
True

(6)長度、最大最小值

通過內建函數len、max和min可以返回序列中所包含元素的數量、最大和最小元素。

str1='Hello'
print (len(str1))
print (max(str1))
print (min(str1))
num1=[1,2,1,4,123]
print (len(num1))
print (max(num1))
print (min(num1))

輸出:

5
o
H
5
123
1

二、映射(字典)

映射中的每個元素都有一個名字,如你所知,這個名字專業的名稱叫鍵。字典(也叫散列表)是Python中唯一內建的映射類型。

字典的鍵可以是數字、字符串或者是元組,鍵必須唯一。在Python中,數字、字符串和元組都被設計成不可變類型,而常見的列表以及集合(set)都是可變的,所以列表和集合不能作為字典的鍵。鍵可以為任何不可變類型,這正是Python中的字典最強大的地方。

 字典的方法(可能需要重新整理)

函數

說明

D

代表字典對象

D.clear()

清空字典

D.pop(key)

移除鍵,同時返回此鍵所對應的值

D.copy()

返回字典D的副本,只復制一層(淺拷貝)

D.update(D2)

將字典 D2 合並到D中,如果鍵相同,則此鍵的值取D2的值作為新值

D.get(key, default)

返回鍵key所對應的值,如果沒有此鍵,則返回default

D.keys()

返回可迭代的 dict_keys 集合對象

D.values()

返回可迭代的 dict_values 值對象

D.items()

返回可迭代的 dict_items 對象

三、集合

集合(Set)在Python 2.3引入,通常使用較新版Python可直接創建,如下所示:

strs=set(['jeff','wong','cnblogs'])
nums=set(range(10))

看上去,集合就是由序列(或者其他可迭代的對象)構建的。集合的幾個重要特點和方法如下:

(1) 固定集合構造(創建)函數 frozenset

函數

說明

frozenset()

創建一個空的固定集合對象

frozenset(iterable)

用可迭代對象創建一個新的固定集合對象

(2) 集合構造(創建)函數 set

函數

說明

set()

創建一個空的集合對象(不能用{}來創建空集合)

set(iterable)

用可迭代對象創建一個新的集合對象

(3) Python3 集合中常用的方法

方法

意義

S.add(e)

在集合中添加一個新的元素e;如果元素已經存在,則不添加

S.remove(e)

從集合中刪除一個元素,如果元素不存在於集合中,則會產生一個KeyError錯誤

S.discard(e)

從集合S中移除一個元素e,在元素e不存在時什么都不做;

S.clear()

清空集合內的所有元素

S.copy()

將集合進行一次淺拷貝

S.pop()

從集合S中刪除一個隨機元素;如果此集合為空,則引發KeyError異常

S.update(s2)

用 S與s2得到的全集更新變量S

S.difference(s2)

用S - s2 運算,返回存在於在S中,但不在s2中的所有元素的集合

S.difference_update(s2)

等同於 S = S - s2

S.intersection(s2)

等同於 S & s2

S.intersection_update(s2)

等同於S = S & s2

S.isdisjoint(s2)

如果S與s2交集為空返回True,非空則返回False

S.issubset(s2)

如果S與s2交集為非空返回True,空則返回False

S.issuperset(...)

如果S為s2的子集返回True,否則返回False

S.symmetric_difference(s2)

返回對稱補集,等同於 S ^ s2

S.symmetric_difference_update(s2)

用 S 與 s2 的對稱補集更新 S

S.union(s2)

生成 S 與 s2的全集

四、棧、隊列

堆棧:先進后出
隊列:先進先出 FIFO

(1) namedTuple(typename, fields)

from collections import namedtuple
Point=namedtuple('point', ['x','y'])
p=Point(1,2)
print(p.x) #1
print(p.y) #2
print(p) #point(x=1,y=2)

(2)  deque([iterable[, maxlen]])

隊列:先進先出

import queue
Q=queue.Queue()
Q.put(10)
Q.put(5)
Q.put(6)
print(Q) #<queue.Queue object at 0x0000000001DCA198>
print(Q.get())
print(Q.get())
print(Q.get())
print(Q.get()) #阻塞
print(Q.qsize()) #查看大小

雙端隊列,可以快速的從另外一側追加和推出對象

from collections import deque
q=deque([1,2])
q.append('a')#從后面放數據
q.appendleft('b')#從前面放數據
q.insert(1,3)
print(q.pop())#從后面取數據 #a
print(q.popleft())#從前面取數據 #b
print(q) #deque([3, 1, 2])

(3)  OrderedDict([items])

>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是無序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])

(4) defaultdict([default_factory[, ...]])

from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1'])# key1存在
print(dd['key2'])# key2不存在,返回默認值
6. Counter([iterable-or-mapping])
c = Counter('abcdeabcdabcaba')
print c
輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

 

參考鏈接

1. 作者:wiz_333
    出處:https://blog.csdn.net/wizblack/article/details/78909224

2. 作者:Jeff Wong 
    出處:http://jeffwongishandsome.cnblogs.com/ 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM