? ? ? 上個月11月21日完成了字符串章節(jié)的閱讀右犹,心中非常歡喜丹擎,連滾帶爬總算翻過了一道坎执赡,想必接下來的內容能順利些镰踏,哪成想要讀完容器這章,也勢必要再費一番周折沙合。消極的話到此為止奠伪,還是繼續(xù)正文摘要吧。
本章主講內容是數據容器(Container)首懈,包括字符串绊率、由 range() 函數生成的等差數列、列表(List)究履、元組(Tuple)滤否、集合(Set)、字典(Dictionary)挎袜。根據不同的分類方法,這些容器又分為可變容器(Mutable)和不可變容器(Immutable)肥惭《⒁牵可變的有列表、集合蜜葱、字典全景;不可變的有字符串、range() 生成的等差數列牵囤、元組爸黄。集合滞伟,又分為 Set 和 Frozen Set;其中炕贵,Set 是可變的梆奈,Frozen Set 是不可變的。字符串称开、由 range() 函數生成的等差數列亩钟、列表、元組是有序類型(Sequence Type)鳖轰,而集合與字典是無序的清酥。另外,集合沒有重合元素蕴侣。分類匯總圖表如下:
迭代
數據容器里的元素是可以被迭代的(Iterable)焰轻,為便于處理,它們其中包含的元素昆雀,可以被逐個訪問辱志。由于數據容器的可迭代性,加上操作符 in忆肾,在 Python 語言里寫循環(huán)格外容易且方便(以字符串這個字符的容器作為例子):
for c in 'Python':
? print(c)
P
y
t
h
o
n
在 Python 中荸频,簡單的 for 循環(huán),只需要指定一個次數就可以了客冈,因為有 range() 這個函數:
for i in range(10):
? print(i)
0
1
2
3
4
5
6
7
8
9
Python 也不只有 for 循環(huán)旭从,還有 while 循環(huán),在必要的時候可以寫復雜的計數器场仲。
列表(List)
列表和字符串一樣和悦,是個有序類型(Sequence Type)的容器,其中包含著有索引編號的元素渠缕。列表中的元素可以是不同類型鸽素。
列表的生成
生成一個列表,有以下四種方式:
a_list = []
b_list = [1, 2, 3]
list(), or list(iterable)? ? ? ? ? ? # 這是 Type Casting
[(expression with x) for x in iterable]
列表的操作符
列表的操作符和字符串一樣亦鳞,因為它們都是有序容器馍忽。列表的操作符有:
拼接:+(與字符串不一樣的地方是,不能用空格 ' ' 了)
復制:*
邏輯運算:in 和 not in燕差,<遭笋、<=、>徒探、>=瓦呼、!=、==
兩個列表可以被比較测暗,即央串,可以進行邏輯運算磨澡;比較方式也跟字符串一樣,從兩個列表各自的第一個元素開始逐個比較质和,“一旦決出勝負馬上停止”
根據索引提取列表元素
列表當然也可以根據索引操作稳摄,但由于列表是可變序列,所以侦另,不僅可以提取秩命,還可以刪除,甚至替換褒傅。
運行下列語句:
import random
n = 3
a_list = [random.randrange(65, 91) for i in range(n)]
b_list = [chr(random.randrange(65, 91)) for i in range(n)]
print(a_list)
c_list = a_list + b_list + a_list * 2
print(c_list)
print()
# 根據索引提绕瘛(Slicing)
print(c_list[3])? ? ? ? # 返回索引值為 3 的元素值
print(c_list[:])? ? ? ? # 相當于 c_list,返回整個列表
print(c_list[5:])? ? ? # 從索引為 5 的值開始直到末尾
print(c_list[:3])? ? ? # 從索引 0 開始殿托,直到索引 3 之前(不包括 3)
print(c_list[2:6])? ? ? # 從索引 2 開始霹菊,直到索引 6 之前(不包括 6)
print()
# 根據索引刪除
del c_list[3]
print(c_list)? ? ? ? ? # del 是個命令,del c_list[3] 是一個語句支竹;不能這么寫:print(del c_list[3])
del c_list[5:8]
print(c_list)
print()
# 根據索引替換
c_list[1:5:2] = ['a', 2]? # s[start:stop:step] = t旋廷,跟 range 的三個參數類似;
? ? ? ? ? ? ? ? ? ? ? ? # len(t) = len([start:stop:step]) 必須為真
輸出結果如下:
[77, 66, 79]
[77, 66, 79, 'L', 'Z', 'R', 77, 66, 79, 77, 66, 79]
L
[77, 66, 79, 'L', 'Z', 'R', 77, 66, 79, 77, 66, 79]
['R', 77, 66, 79, 77, 66, 79]
[77, 66, 79]
[79, 'L', 'Z', 'R']
[77, 66, 79, 'Z', 'R', 77, 66, 79, 77, 66, 79]
[77, 66, 79, 'Z', 'R', 77, 66, 79]
[77, 'a', 79, 2, 'R', 77, 66, 79]
需要注意,列表(List)是可變序列礼搁,而字符串(str)是不可變序列饶碘,對字符串來說,雖然也可以根據索引提取馒吴,但沒辦法根據索引刪除或者替換扎运。
字符串常量(String Literal)是不可變有序容器,雖然字符串也有一些 Methods 可用饮戳,但那些 Methods 都不改變它們自身豪治,而是在操作后返回一個值給另外一個變量。而對于列表這種可變容器扯罐,我們可以對它進行操作负拟,結果是它本身被改變了。見如下示例:
s = 'Python'
L = list(s)
print(s)
print(L)
del L[2]
print(L) # 用 del 對 L 操作之后歹河,L 本身少了 1 個元素
返回結果
Python
['P', 'y', 't', 'h', 'o', 'n']
['P', 'y', 'h', 'o', 'n']
列表可用的內建函數
列表和字符串都是容器掩浙,它們可使用的內建函數也其實都是一樣的:
len()
max()
min()
示例:
import random
n = 3
# 生成 3 個隨機數,構成一個列表
a_list = [random.randrange(65, 91) for i in range(n)]
b_list = [chr(random.randrange(65, 91)) for i in range(n)]
print(a_list)
print(b_list)
# 列表可以使用操作符 + 和*
c_list = a_list + b_list + a_list * 2
print(c_list)
a_list *= 3
print(a_list)
# 內建函數操作 len()秸歧、max()厨姚、min()
print(len(c_list))
print(max(b_list)) # 內建函數內部做了異常處理,可以比較字符和數字 —— 初學者最討厭這種事情了……
print(min(b_list)) # 注意寥茫,max() 和 min() 應用的是 b_list, len() 應用的是 c_list —— 請自行找到對應的 list 進行分析遣蚀。
print('X' not in b_list)
返回結果
[89, 84, 85]
['X', 'B', 'X']
[89, 84, 85, 'X', 'B', 'X', 89, 84, 85, 89, 84, 85]
[89, 84, 85, 89, 84, 85, 89, 84, 85]
12
X
B
False
Methods
字符串常量和 range() 都是不可變的(Immutable)矾麻;而列表則是可變類型(Mutable type)纱耻,所以芭梯,它最起碼可以被排序 —— 使用 sort() method ,如果列表中的元素全都是由字符串構成的,當然也可以排序.
注意:被比較的元素應該是同一類型 ,不是由同一種數據類型元素構成的列表弄喘,不能使用 sort() Method玖喘。
可變序列還有一系列可用的 Methods:a.append(),a.clear()蘑志,a.copy()累奈,a.extend(t),a.insert(i急但,x)澎媒,a.pop([i]),a.remove(x)波桩,a.reverse()
import random
示例:
n = 3
a_list = [random.randrange(65, 91) for i in range(n)]
b_list = [chr(random.randrange(65, 91)) for i in range(n)]
print(a_list)
c_list = a_list + b_list + a_list * 2
print(c_list)
# 在末尾追加一個元素
c_list.append('100')
print(c_list)
# 清空序列
print()
print(a_list)
a_list.clear()
print(a_list)
print()
# 拷貝一個列表
d_list = c_list.copy()
print(d_list)
del d_list[6:8]
print(d_list)
print(c_list)? ? ? ? ? ? # 對一個拷貝操作戒努,不會更改 “原件”
print()
# 演示拷貝 .copy() 與賦值 = 的不同
e_list = d_list
del e_list[6:8]
print(e_list)
print(d_list)? ? ? ? ? ? # 對 e_list 操作,相當于對 d_list 操作
# 在末尾追加一個列表
print()
print(a_list)
a_list.extend(c_list)? ? ? # 相當于 a_list += c_list
print(a_list)
# 在某索引位置插入一個元素
print()
print(a_list)
a_list.insert(1, 'example')? # 在索引 1 的位置插入 'example'
a_list.insert(3, 'example')? # 在索引 3 的位置插入 'example'镐躲;
print(a_list)
# 排序
# a_list.sort() 這一句會出錯储玫,因為當前列表中的元素,是 int 和 str 混合的萤皂。
print()
print(a_list)
a_list.reverse()
print(a_list)
x = a_list.reverse() # reverse() 只對當前序列操作撒穷,并不返回一個逆序列表;返回值是 None
print(x)
返回結果
[90, 88, 73]
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73]
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 88, 73]
[]
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 88, 73, 'T', 'N', 'Y', 73, 90, 88, 73, '100']
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 88, 73, 'T', 'N', 'Y', 88, 73, '100']
[90, 88, 73, 'T', 'N', 'Y', 88, 73, '100']
[]
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 88, 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 'example', 88, 'example', 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
[90, 'example', 88, 'example', 73, 'T', 'N', 'Y', 90, 88, 73, 90, 88, 73, '100']
['100', 73, 88, 90, 73, 88, 90, 'Y', 'N', 'T', 73, 'example', 88, 'example', 90]
None
命令del裆熙,Method a.pop([i])和a.remove(x)都與刪除單個元素相關端礼,請注意它們之間的區(qū)別。
import random
n = 3
a_list = [random.randrange(65, 91) for i in range(n)]
print(a_list)
# 插入
print()
a_list.insert(1, 'example')? # 在索引 1 的位置插入 'example'
# 刪除
print()
print(a_list)
a_list.remove('example')? ? ? # 去除 'example' 這個元素弛车,如果有多個 'example'齐媒,只刪除第一個
print(a_list)
# pop() 刪除并返回被刪除的值
print()
print(a_list)
p = a_list.pop(2)? ? ? # 去除索引為 2 的元素,且返回元素的值纷跛,賦值給 p
print(a_list)
print(p)
# pop() 與 del喻括,或者 remove() 的區(qū)別
print()
a_list.insert(2, 'example')
a_list.insert(2, 'example')
print(a_list)
del a_list[2]
print(a_list)
print()
print(a_list.remove('example')) # a_list.remove() 這個 Method 的返回值是 None
print(a_list)
返回結果:
[88, 84, 69]
[88, 'example', 84, 69]
[88, 84, 69]
[88, 84, 69]
[88, 84]
69
[88, 84, 'example', 'example']
[88, 84, 'example']
None
[88, 84]
容器特性總結
路漫漫其修遠兮,唯有耐心隨其愿贫奠。加油唬血!