1. 程式人生 > >Python 基本資料型別(四): 列表型別

Python 基本資料型別(四): 列表型別

content

- 列表的建立
- 列表的操作
- 列表的相關方法
- 列表的遍歷
- 列表的推導式
- 專欄:解析淺拷貝,深拷貝

1. 列表的建立

# 語法:列表名=[元素1,元素2....]

# 列表的記憶體結構:記憶體圖
# 計算機記憶體中列表是有列表物件的。不同的列表物件是不同的。
  
names=["tom","jerry","kate",1,2,[4,5]]
print(names,type(names))
# ['tom', 'jerry', 'kate', 1, 2, [4, 5]] <class 'list'>

names2=["tom"
,"jerry","kate",1,2,[4,5]] print(id(names),id(names2)) # 1530963606344 1530963621000 可變資料型別即是值一樣,id也不一樣 print(id(names[0]),id(names2[0])) # 1530709131704 1530709131704 但他們第一個元素的id是一樣,因為是不可變資料型別 print(id(names[3]),id(names2[3])) # 1814457376 1814457376 同上 print(id(names[5]),id(names2[5])) # 1530963493832 1530963621192 id不一樣,因為是可變資料型別
print(id(names[5][0]),id(names2[5][0])) # 1814457472 1814457472 id一樣,因為是不可變資料型別
# 定義空列表
nulllist=[]
print(nulllist,type(nulllist))
# [] <class 'list'>

print(len(nulllist))
# 0
# 列表型別的布林轉換
# 至少有一個元素  True,沒有元素 Fasle
names=["tom","jerry","kate",1,2,[4,5]]
nulllist=[]
print(bool(nulllist))
print
(bool(names)) # False # True

2. 列表的操作

(1)運算子
# 		+ * in not in  is  is not  == <  >  =
# 注意:  +  * ,合併原列表中的元素,形成新列表。

# + 是合併, 將兩個列表的元素合在一起,形成新的列表。新建立列表物件進行合併
a=[1,2]
b=[3,4]
print(a+b,a,b)
# [1,2,3,4]
#注意不是這樣 [[1,2],[3,4]]
# * 是重複 將列表中的元素進行重複,形成新的列表
a=[1,2]
b=[3,4]
print(a*3)  
# [1, 2, 1, 2, 1, 2]
# 注意:不是這樣[[1,2],[1,2],[1,2]]
print(a*2+b*3)
# [1, 2, 1, 2, 3, 4, 3, 4, 3, 4]
# in 和 not in: 元素是否在列表物件當中
a=[1,2,3,4,"a"]
print(1 in a)
# True
x="abc"
print("a" in x)  
# True
# 注意:列表中的元素可以是多種型別,字串中的元素就是單個字串
# is 和 is not 判斷物件是否是同一個
# a=[1,2,3]
# b=[1,2,3]
# c=a
# print(a is b) # 注意畫記憶體圖 # False
# print(a is c) # True  # 再把c繫結到a上
# < > 將列表中的元素逐個比較(根據ascii碼比較)
# print([1,2,3]<[4])
# True
(2)索引
# 獲得列表中的單個元素
# 語法: 列表名[index]
# index 正數,負數 0  左到右,第一個0   從右到左第一個是-1
# index如果越界會錯
# 界限-len(li) len(li)-1
# names=["tom","jerry","kate",1,2,[4,5]]
# print(names[0])
# print(names[5])
# print(names[6])
# x=names[5]
# print(x[0])
# print(names[5][0])  # 二維列表
# #二維列表的元素判斷

# names=["tom","jerry","kate",1,2,[4,5]]
# print(4 in names)     
# False
# print(4 in names[5])  
# True
# 列表是可變的資料型別
# 元素可以被修改 ## 單單指列表這個物件
# x="abc"
# x[0]="l"
# 可變的資料型別:可以被修改
# 在同一個id下,內容可以被修改。
names=["tom","jerry","kate",1,2,[4,5]]
print(id(names)) # 2185102998344
names[0]="tom1"
print(names) #  修改了
print(id(names)) ## id也修改了,2185102998344
(3)切片
# 獲取一定區域內的多個元素
# 語法:列表名[start:end:step]
# start 預設0
# end  預設值len(list)
# step 預設1
# 注意方向,負數,從右到左,正數,從左到右

a=["aaa","bb","cc","dd","ee","ff"]
print(a[0:2])
# ['aaa', 'bb'] 注意:切邊前開後閉!!!
print(a[-1:-3:-1]) 
# ['ff', 'ee'] 
# # 整切片: 
# 列表的整切片跟原來物件內容相等,但是不是同一個id,不是同一個物件,所以列表的整切片是新建立的物件

# a=["aaa","bb","cc","dd","ee","ff"]
# b=a[:]
# print(id(a),id(b)) 
# 1798109147464 1798109147400  id不一樣
# print(a[::-1])  
# 逆序輸出
# 切片的修改和刪除 
# 通過列表的切片可以修改列表中一定區域元素 
# 通過切片修改列表一定要賦予列表

# a = ["aaa","bb","cc","dd","ee","ff"]
# print(a[1:4]) 
# 切出來的部分
# a[1:4]=[1,2,3,4,5] ## 把切出來的部分修改成你要的內容
# a[1:4]=[]  ## 把切出來的部分刪除掉
# print(a)
# 如果使用列表的切片進行賦值時,如果給予的是可迭代物件,會將可迭代物件先變成列表,然後再賦給切片
# 如果給予的不是可迭代物件,會報錯

a = ["aaa","bb","cc","dd","ee","ff"]
a[1:4]="123"
# ['aaa', '1', '2', '3', 'ee', 'ff']
# 如果給予的是可迭代物件 也能達到效果,但是最好是賦值  輸出結果都是:a=["aaa","123","ee","ff"]
print(a)
a[1:4]=["1","2","3"]
print(a)
# ['aaa', '1', '2', '3', 'ee', 'ff'] 這倆都一樣
綜合練習:
# 向列表中插入一個元素、刪除一個元素。
a=["aaa","bb","cc","dd","ee","ff"]
a[1:1]=["new"] # 插入
print(a)
# ['aaa', 'new', 'bb', 'cc', 'dd', 'ee', 'ff']

a[1:2]=[] # 刪除
print(a)
# ['aaa', 'bb', 'cc', 'dd', 'ee', 'ff'] 繼承上面的結果,把新的new刪掉了,否則,就是['aaa', 'cc', 'dd', 'ee', 'ff']

# 交換列表中兩個元素
a=["aaa","bb","cc","dd","ee","ff"]
a[1],a[2]=a[2],a[1]
print(a)
# ['aaa', 'cc', 'bb', 'dd', 'ee', 'ff']

3. 列表的相關方法

(1)新增
# 邏輯是:追加 任意 extend   append insert extend

# append
向列表的尾部追加【一個】元素,是原地操作(在原有列表上做操作)

# a=["A","B","C","D","E","F"]
# print(a.append("GG")) 
# 單純的物件加append方法輸出結果是 None
# print(a) 
# 結果最後追加內容: ['A', 'B', 'C', 'D', 'E', 'F', 'GG']
# replace
# s="abc"
# print(s.replace("a","7"))
# print(s)  
# 輸出結果是abc,所以列表裡的跟字串裡的replace方法不一樣,replace方法未改動原字串;基本上字串裡的都是生成新的字串
# insert
# 向列表中插入指定的 【一個】元素 ## 根據指定位置插入
# a.insert(index,object)
# index: 要插入的位置
# object: 要插入的內容

# a=["A","B","C","D","E","F"]
# a.insert(2,"new")
# print(a)
# 能不能使用insert達到append?可以
# a.insert(len(a),"p")
# print(a)
# + 合併,新建立列表進行合併或者新增元素

# extend 合併,一次追加多個元素,原地修改,在原有列表上追加

# a=["A","B","C","D","E","F"]
# a.extend([1,2,3])  ## ['A', 'B', 'C', 'D', 'E', 'F', 1, 2, 3]
# print(a)
(2)刪除
# pop remove del clear

# pop:刪除指定位置的元素,一次只能刪一個,原地刪除
(記憶python中的pop並不是別的單詞的縮寫,因為pop本身就有“伸出”的意思
# pop的返回值是被刪除掉的元素
# pop中index為空,預設列表中最後一個元素
# pop索引不存在會報錯

# a=["A","B","C","D","E","F"]
# a.pop()
# print(a) 
# 刪除掉最後一個F
# ['A', 'B', 'C', 'D', 'E']

# a.pop(2)
# print(a) 
# ['A', 'B', 'D', 'E', 'F']
# 刪除掉了第二個元素C,是原地操作
# print(a.pop(2)) 
# C 注意:單獨輸出.pop方法,是將選中的元素輸出
# index是要刪除元素的位置
# del 刪除列表中的元素 
(根據索引刪除,跟pop類似,只不過應用的是關鍵字而已)
a=["A","B","C","D","E","F"]
del a[0]
print(a)
# ['B', 'C', 'D', 'E', 'F']

a=["A","B","C","D","E","F"]
del a
print(a)
# name 'a' is not defined
# remove 刪除指定內容的元素,一次只能刪一個,原地刪除
# a=["A","B","C","D","E","F"]
# a.remove("D")
# print(a)
# clear 清空列表中的元素
# a=["A","B","C","D","E","F"]
# a.clear() ## 只是清空a,不是刪除a,刪除a需要用del
# print(a)
# []
(3)檢索、統計
a=["A","B","C","D","E","F","A","A"]
# index返回元素所在的位置,可以指定start和end
print(a.index("E"))
print(a.index("gg")) # 如果找不到會報錯,脾氣不好
# 'gg' is not in list

# count: 統計某個元素的個數
# print(a.count("A"))
(4)反向,排序
#反向

# a=["A","B","C","D","E","F","A","A"]
# a.reverse() # 原地反向, 原列表就已經被反向,跳一步,輸出原數列
# print(a)
# ['A', 'A', 'F', 'E', 'D', 'C', 'B', 'A']

# a=["A","B","C","D","E","F","A","A"]
# print(list(reversed(a)))  # reversed內建方法不是原地反向,直接輸出
# print(a) 
# ['A', 'B', 'C', 'D', 'E', 'F', 'A', 'A']   a沒有改變,不是原地反向,是內建方法
# 排序

a=["A","B","C","D","E","F","A","A"]
a.sort()  
a.sort(reverse=True)
# 預設reverse引數=False升序 , 原地排序
print(a)
# ['A', 'A', 'A', 'B', 'C', 'D', 'E', 'F']

# a=["A","B","C","D","E","F","A","A"]
# print(sorted(a))  ##和reversed(a)一樣,不是原地排序,新建列表進行排序 ,返回值是原列表,是內建方法
# ['A', 'A', 'A', 'B', 'C', 'D', 'E', 'F']
# print(a) 	
# ['A', 'B', 'C', 'D', 'E', 'F', 'A', 'A']

# b="addfadjlkg"
# print(sorted(b)) ## 返回值是原列表
# print("".join(sorted(b)))  ## 用join方法 將sorted後返回的列表 拼接成字串
# 形成光滑的字串,沒有中括號,沒有引號 : aadddfgjkl
(5)列表的複製
① 賦值
# 記憶體圖

# a=[1,2,[3,4]]
# b=a
# print(b)
# print(id(a),id(b)) 
# a和b是同一個物件 地址 2710116604296 2710116604296

# a[0]="new"
# a[2][0]="new"
# print(a,b)
# print(a is b)  
# True 本身就是賦值方法 即使更改某個元素也一樣
在這裡插入程式碼片
② 淺拷貝
# 在列表下copy方法
	# copy包下copy
	# 整切片

	# 只拷貝當前列表物件(第一層),其他層無論是可變型別還是不可變型別都不復制
	# 如果元素是不可變資料型別,原物件的修改不影響拷貝物件,
	# 如果元素是可變資料型別,元物件的修改影響拷貝物件。
# 記憶體圖  
# 淺拷貝特點:	# 只拷貝當前列表物件(第一層),其他層無論是可變型別還是不可變型別都不復制

# 在列表下copy方法copy方法
a=[1,2,[3,4]]
b=a.copy()
print(id(a),id(b))
print(id(a[0]),id(b[0]))
print(id(a[2]),id(b[2]))
# 1916631432008 1916631446856
# 1814457376 1814457376
# 1916631319496 1916631319496

a=[1,2,[3,4]]
# c=[1,2,[3,4]]

b=a.copy()
print(id(a),id(b))
# 不一樣 1684392688456 1684392703304

a[0]="new"
a[2][0]="new"
print(a,b)
# a: ['new', 2, ['new', 4]]    b:  [1, 2, ['new', 4]]
# 注意: 對於可變型別的元素(列表),你變了我就跟著變,不可變資料型別就沒有變

print(id(a[0]),id(b[0]))
# 2216897637880 1814457376 不一樣

print(id(a[2]),id(b[2]))
# 2060635131720 2060635131720

# 所以結論是:	# 如果元素是不可變資料型別,原物件的修改不影響拷貝物件,
				# 如果元素是可變資料型別,元物件的修改影響拷貝物件。

# copy包下copy
import copy
a=[1,2,[3,4]]
d=copy.copy(a)
print(id(a),id(d))
# 不一樣 1684392688456 1684392703304

print(id(a[0]),id(d[0]))
# 一樣 1814457376 1814457376

print(id(a[2][0]),id(d[2][0]))
# 一樣 1814457440 1814457440
# 整切片
a=[1,2,[3,4]]
b=a[:]
print(id(a),id(b))  
# 2296421824264 2296421783944  地址不一樣
③ 深拷貝
# copy包下deepcopy方法
# 一直拷貝到不可變元素為止,不止拷貝一層

# import copy
# a=[1,2,[3,4]]
# b=copy.deepcopy(a)
# # c=[1,2,[3,4]]
# print(id(a),id(b)) 
#不一樣: 2016033397512 2016033460296

# print(id(a[0]),id(b[0])) 
# 1672965152 1672965152 不可變資料型別,不變

# print(id(a[2]),id(b[2])) 
# 2016033397320 2016033398728 可變資料型別,變化

# print(id(a[2][0]),id(b[2][0])) 
# 1672965216 1672965216 一樣
# import copy
# a=[1,2,[3,4]]
# b=copy.deepcopy(a)
# a[0]="new"
# a[2][0]="new"
# print(a,b)
# 有記憶體圖,只有不可變型別不變,可變資料型別都是新的

4. 列表的遍歷

# 第一種
#  li=[1,2,3,4,5]
# for i in li:
#     print(i) 
# 第二種 根據索引遍歷
# li=[1,2,3,4,5]
# for i in range(5):  ## 一共5個元素,
#     print(li[i])   ## 我要獲得每個元素,就是li的[i]個元素,這個更好用

# 有時候涉及到交換位置,必須還會根據索引遍歷
# 這兩種方法都可以
# 第三種 enumerate
# li=[1,2,3,4,5]
# for index,i in enumerate(li):
#     print(index,i)  ## 索引 元素 ## 這三種方法都可以
# 遍歷多維列表:巢狀for迴圈
li=[[1,2],[3,4]]

# for i in li:
#     for j in i:
#         print(j)
# 用range怎麼用?

li=[[1,2],[3,4]]

for i in range(2): 
# 2個元素  當前i是索引,不是元素,所以得遍歷索引;不能in i,得in li的[i]個元素
    for j in range(len(li[i])): # li[i]是當前元素,要先獲得它的len,再獲得索引
        print(li[i][j]) # 這是是li第i個元素的第j個元素
"""
1
2
3
4
"""
li=[[1,2],[3,4]]

for i in range(len(li)):
	for j in range(len(li[i])):
		print(li[i][j])
"""
1
2
3
4
"""
li = ['a','b','c']
for caocao in li: ## 迴圈條件
    print('給定的字母是   %s' %caocao)
    print(li) ## 所以li其實是給定的次數
    print(caocao)
"""
    給定的字母是   a
['a', 'b', 'c']
a
給定的字母是   b
['a', 'b', 'c']
b
給定的字母是   c
['a', 'b', 'c']
c
    """
li = list(range(5))
print(li,type(li))
# [0, 1, 2, 3, 4] <class 'list'>

for i in list(range(5)):
	print(i)
	print(list(range(5)))
"""
0
[0, 1, 2, 3, 4]
1
[0, 1, 2, 3, 4]
2
[0, 1, 2, 3, 4]
3
[0, 1, 2, 3, 4]
4
[0, 1, 2, 3, 4]

"""

5. 列表的推導式

# 簡化的構建新列表
# 當已經具有一個迭代物件,希望新構建列表
# 格式:[表示式 for i in 迭代物件 if 條件] 
# 表示式就是形成新列表的元素
# 簡化的構建新列表
# 當已經具有一個迭代物件,希望新構建列表
# 格式:[表示式 for i in 迭代物件 if 條件] 
# 表示式就是形成新列表的元素

專欄:解析淺拷貝,深拷貝

Question:
闡述一下python中列表的深拷貝與淺拷貝

淺拷貝:列表下的copy方法,copy包下的copy方法,列表的切片
只複製當前列表物件的第一層。
深拷貝:copy包下的deepcopy
一直複製到不可變型別物件為止。
# 程式碼嘗試:

# a = [1,[2,3],4]
# b = a.copy()

# print(id(a),id(b)) # id不一樣,複製成功;第一層
# print(id(a[0]),id(b[0]))  #id一樣,沒有複製;第二層
# print(id(a[1]),id(b[1])) #id一樣,第二層
# print(id(a[1][0]),id(b[1][0])) #id一樣,沒有複製;第三層
# a[0] = 'y'
# print(id(a[0]),id(b[0])) # id不一樣 b不受影響
# print(id(a[1]),id(b[1])) #id一樣
# print(id(a[1][0]),id(b[1][0])) #id一樣 b受影響
# a[1] = 'y'
# print(id(a[0]),id(b[0])) # id一樣 b受影響
# print(id(a[1]),id(b[1])) #id不一樣
# print(id(a[1][0]),id(b[1][0])) #id更不一樣 b不受影響
# a[1][0] = 'y'
# print(id(a[0]),id(b[0])) # id一樣 b受影響
# print(id(a[1]),id(b[1])) #id一樣
# print(id(a[1][0]),id(b[1][0])) #id一樣 b受影響
# import copy

# a = [1,[2,3],4]
# b = copy.deepcopy(a)

# print(id(a),id(b)) # id不一樣,複製成功,第一層
# print(id(a[0]),id(b[0]))  #id一樣
# print(id(a[1]),id(b[1])) #id不一樣
# print(id(a[1][0]),id(b[1][0])) #id一樣
# a[0] = 'y'
# print(id(a[0]),id(b[0])) # id不一樣 b不受影響
# print(id(a[1]),id(b[1])) #id不一樣
# print(id(a[1][0]),id(b[1][0])) #id一樣 b受影響

# a[1] = 'y'
# print(id(a[0]),id(b[0])) # id一樣 b受影響
# print(id(a[1]),id(b[1])) #id不一樣
# print(id(a[1][0]),id(b[1][0])) #id不一樣 b不受影響
# a[1][0] = 'y'
# print(id(a[0]),id(b[0])) # id一樣
# print(id(a[1]),id(b[1])) #id不一樣
# print(id(a[1][0]),id(b[1][0])) #id不一樣