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/
