容器類數據類型python內置數據類型中,有一類數據類型,它能像容器那樣存儲不同的元素。列表list、元組tuple、字符串str、字典dict、集合set都是屬於容器類型。
一、容器類對象的幾種類別
容器:container 序列:sequence 映射:mapping
序列(sequence)是一種數據結構,是有序的容器類型,list、str和tuple都屬於序列,其中列表是可變的(你可以修改其內容),而元組和字符串是不可變的(一旦創建,內容就是固定的)。
熟悉Python中的內存機制,這種不可變是指類型內的元素是不能進行修改的
注:像下面介紹的字符串的切割,鏈接等操作,看起來修改了字符串,實質上並沒有修改原來的字符串,在內存中字符串還是原來的字符串。操作在內存中產生了新的字符串
序列索引值:序列的每個元素都有索引值,用索引值我們能訪問到指定元素,
相比於C語言中的數組是基於0的下標索引,即長度爲n的數組,第一個值的下標爲0,最後一個元素的下標爲n-1 。
Python中序列索引值有更靈活的“定義”,不但有順序索引:0~(n-1),還有倒序索引:-1~ -n ,-n是第一個元素,-1是最後一個元素。
看起來我們可把序列索引值以理解爲:相對於第一個元素的偏移量。這樣的倒序索引和正序索引看起來就比較自然了。
序列的特有操作:切片、鏈接+和重複*
-
切片 : 切片適合有序的容器類型(序列)。
語法:s = [start:end:step]
# start:開始位置, end:結束位置;start和end指定了切片的範圍.
# step: 步進值,從開始位置到結束位置的步進值,。step可指定爲正數(步進方向可認爲是順序)或負數(步進方向可認 爲是逆序)。默認步進值爲1 因此可省略最後一個冒號和step : s[start:end]
# 報錯的情況: 按照步進的方向,開始到結束的區間不能越過邊界,不符合切片範圍的會返回對應的空序列 [ ] () ‘ ‘
# start和end可以不指定,默認是步進方向的首尾位置。
>>> lt = [0, 1, 2, 3, 4, 5]
>>> lt[::2]
[0, 2, 4]
>>> lt[::-2]
[5, 3, 1]
# 指定start和end的時候,切片範圍遵循左開右閉原則:切片範圍不包含end。 開始值和結束值都是遵循序列索引值的。
注意:在不指定開始位置和結束位置的時候,結束位置是被包含在切片範圍內的。
>>> lt = [0, 1, 2, 3, 4, 5, 6]
>>> lt[::2]
[0, 2, 4, 6]
# 切片操作是爲了訪問序列的一部分。 靈活的使用序列的索引值和步進值來解決需求。
# 0.查找序列的後三個元素
>>> s = 'helloworld'
>>> s[-3:]
'rld'
# 1.序列元素逆序
>>> s = 'hello,world!'
>>> s[::-1]
'!dlrow,olleh'
# 切片賦值:另外對於列表,可以使用賦值語句給切片賦值
注意:賦值語句的右邊必須是可迭代對象(iterable),如果是字典的話,會將其鍵賦值到切片位置
>>> lt = [0, 1, 2, 3, 4, 5]
>>> lt[0:2]=[99]
>>> lt
[99, 2, 3, 4, 5]
>>> lt[0:2] = {'name': 'marsen'}
>>> lt
['name', 3, 4, 5]
-
鏈接+和重複*:
序列支持 + 和 * 操作的,本質上是生成了新的序列,原來的序列保持不變
# 鏈接操作 + 是對序列元素的拼接
>>> s = 'hello'
>>> s + ',' + 'world!'
'hello,world!'
>>> lt = [0, 1, 2]
>>> lt + [3, 4] + [5]
[0, 1, 2, 3, 4, 5]
>>> tp = (0, 1, 2)
>>> tp + (3, 4) + (5,)
(0, 1, 2, 3, 4, 5)
# 重複操作 * 是序列元素的重複
>>> tp = (0, 1)
>>> tp * 3
(0, 1, 0, 1, 0, 1)
>>> tp
(0, 1)
>>> lt = [0, 1]
>>> lt * 3
[0, 1, 0, 1, 0, 1]
>>> lt
[0, 1]
>>> s = 'hi'
>>> s * 3
'hihihi'
>>> s
'hi'
映射(mapping),通過名稱訪問其各個值的數據結構,稱之爲mapping, 字典(dict)是Python中唯一的內置映射類型。
其他容器類型:集合(set)
二、容器類對象通用操作
容器類變量有一些共同點:
-
取值(訪問):container [ 索引 ]
-
遍歷: 使用for in進行元素遍歷
-
成員判斷: 使用成員運算符 in 來檢查元素是否存在
-
計算長度:len(container): 使用系統函數len( )返回容器內項的數量,對於字典來說,返回的就是鍵值對的個數
-
比較: max() /min() 以及 同類型對象之間 > < 的比較
0,取值(訪問):container [ 索引 ]
變量後跟中括號:‘[ ]’,括號內是索引。對於序列來說,可以使用這種方式根據索引值訪問元素,對於字典來說索引就是鍵。
1,遍歷
容器類對象都屬於可迭代對象(iterable),因此都能使用for in 進行遍歷。
能進行for in 遍歷操作的對象是可迭代對象
from collections import Iterable
st = [5, 1, 4, 2, 3, 1]
print(isinstance(st, Iterable))
### True
下面討論以下比較有趣的遍歷:對集合set 內元素的遍歷:集合set 的for in :集合內的元素都是無序的,因此遍歷的時候會發現,每次遍歷元素的順序都不一樣。
st = {'b', 'c', 'a', 1, 5}
for i in st:
print(i)
# 第一次運行
b
1
a
5
c
# 第二次運行
1
5
a
c
b
但是,集合內元素如果是數字的話,那麼數字之間順序是永遠正序的,上面的遍歷例子中,1是比5先遍歷出來的,用個純數字的集合來實驗,如下:
st = {3, 4, 1, 5}
for i in st:
print(i)
###
1
3
4
5
2,成員判斷: 使用成員運算符 in 來檢查元素是否存在。
-
對於字典來說,使用 in 是判斷字典中是否存在對應的鍵
>>> dt = {'name': 'marsen', 'age': 18}
>>> 'name' in dt
True
>>> 'marsen' in dt
False
# (k, v) in d 是不能實現判斷鍵值對是否存在的功能,要實現項成員資格檢查,要藉助字典的方法items: (k, v)in dt.items()
>>> ('age', 18) in dt
False
>>> ('age', 18) in dt.items()
True
-
對於其它的容器對象來說都是檢查對象中元素是否存在的
# 檢查單個元素在容器對象中是否存在 (列表,元組,集合)
>>> lt = [0, 1, 2, 4, 5]
>>> [0, 1] in lt
False
>>> 2 in lt
True
>>> tp = (1, 2, 3)
>>> 1 in tp
True
>>> (1,) in tp
False
>>> st = {1, 2, 3, 4}
>>> 1 in st
True
>>> {1, 2} in st
False
# 對字符串來說,不僅能夠檢查單個字符是否存在,還能檢查字串是否存在
>>> s = 'hello'
>>> 'hel' in s
True
>>> 'h' in s
True
>>> 'ho' in s
False
3,計算長度:len(container): 使用系統函數len( )返回容器內項的數量,對於字典來說,返回的就是鍵值對的個數
4,比較: max() /min() 以及 > < 的比較
-
最大元素和最小元素
Python中提供了內置函數max()和min(),可用於找出容器中最大和最小的元素。
>>> max((8, 1, 3, 5))
8
>>> max([1, 8, 5, 10])
10
>>> min([1, 8, 5, 10])
1
有關max和min函數的使用,請轉看另外的博客,專門對這兩個內置函數進行詳細探討:
max(iterable,[,key=]) / min(iterable, [,key=])
這兩個內置函數的使用中,我們要注意的是迭代對象的元素之間必須是能進行大小比較的,關於大小比較的討論下面將會進行討論。
-
容器對象之間> <的比較
Python中不同類型的對象之間是無法進行比較的,跟整型,浮點型和複數之間的數字大小比較不同,容器類對象內包含不同的元素,它們之間就比較複雜。
首先說字符串str之間的比較,兩個字符串之間的比較,首先是第一個元素進行比較,比較的原則遵循ASCII碼值,如果比較出來大小,那麼將確定字符串的大小,如果第一個字符是相同的,那麼會接着比較第二個字符,如果一個字符串是另一個字符串的開頭,那麼較長的字符串爲較大的。
元組之間進行比較:進行比較的時候也是先從第一個元素進行比較,比較出來結果之後,則後面的就不進行比較。
注:兩個相互比較的元組之間,對應索引位置上的元素必須是同類型可比較的對象。否則會報錯
>>> (100,'a')>(101,)
False
>>> (100,'a')>(100,)
True
列表和元組一樣,也是先從第一個元素開始進行比較,兩個列表中對應索引位置上元素都必須是同類型可比較的對象。
>>> [100, 'a']>[101]
False
>>> [100, 'a']<[100,'b']
True
上面說的是序列的大小比較操作,下面說一下剩下幾個容器類的數據類型的比較:
- 集合set之間的比較是判斷是否是子集,而不是比較其元素大小,大小關係就是集合之間父子集的關係
兩個集合st1和st2 , 表達式st1 < st2 當st1是st2的子集, 結果纔會是True
>>> {1, 3, 'a'} > {1, 3}
True
>>> {1, 3, 'a'} > {1, 3,'b'}
False
>>> {1, 3, 'a'} < {1, 3, 5,'a'}
True
- 字典dict之間是不能比較的