為什麼要用到 list ?
舉個例子:1
names = 'Rogers Stark Thor Loki Natasha'
雖然 names 可以存取人名,但是如果要增加或者存取其中一個人的名字就GG。
所以我們使用 list 來存取這些人名,list在python是以[]來表示的。
而且list內容是可以更改的,像是排序、加入、刪除等等。
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
取得 list 的值
這時我想要得到Jenny,該怎麼取呢?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | print(names[4]) |
4 | |
5 | ---------執行結果------- |
6 | |
7 | Jenny |
等等Jenny不是在第五個嗎?怎麼會是names[4]?
這是因為電腦存數據時,不是從1開始算的,是從0開始算起的,所以Jenny是在第四個。
我們可以使用[index]來取出list的值囉,跟C語言的array類似。
那…能不能一次把 ‘Tim’和’Amy’取出來?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | print(names[2:3]) |
3 | |
4 | ---------執行結果--------- |
5 | |
6 | ['Tim'] |
奇怪?[2:3] 不是2~3的意思嗎?怎麼只有Tim一個人?
哦~~原來我用法錯誤!!
正確是這樣
[Start:End-1]
end是要減1的
使用[Start:End-1] return 是一個 list 喔!
如果我不知道list有幾個,但我想取出最後一個怎麼辦?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | print(names[-1]) |
3 | |
4 | ---------執行結果--------- |
5 | Jenny |
所以正的(包含0)就是從左到右取值,負的就是從右到左取值,所以倒數第二個就是names[-2]
那這樣取全部是不是這樣?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | print(names[0:-1]) |
3 | |
4 | |
5 | ---------執行結果--------- |
6 | ['Mike', 'John', 'Tim', 'Amy'] |
拉雞!又不對,阿!我忘了是 使用[Start:End-1]
所以應該是names[0:0],但這個很鳥欸 = =
有個更牛逼的方法,就是如果你要頭跟尾就空白。
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | print(names[:2]) # 第0個到第1個 |
4 | print(names[1:]) # 第1個到最後1個 |
5 | print(names[:]) # 全部 |
6 | |
7 | ---------執行結果--------- |
8 | |
9 | ['Mike', 'John'] |
10 | ['John', 'Tim', 'Amy', 'Jenny'] |
11 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
棒!果然如預期!
加入元素
喔喔 突然要加一個人,要怎麼加呢?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | names.append("Curry") |
3 | |
4 | print("After append() ",names) |
5 | |
6 | ---------執行結果--------- |
7 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny','Curry'] |
append()
是list內建function功能是加進list的尾端
但是我想加到list的任何位置怎麼辦?
1 | |
2 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
3 | names.insert(1,"insert1_Jack") |
4 | names.insert(3,'insert3_Tom') |
5 | |
6 | ---------執行結果--------- |
7 | ['Mike', 'insert1_Jack', 'John', 'insert3_Tom', 'Tim', 'Amy', 'Jenny'] |
原本在[1]的’John’被往後移一格了,’Tim’也是,代表insert()
不會取代原來的元素。
串接list
要把一個list接在令一個list要怎麼用呢?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | others = ['Tom','Curry'] |
3 | |
4 | names.append(others) |
5 | print(names) |
6 | |
7 | ---------執行結果--------- |
8 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', ['Tom', 'Curry']] |
好像不是這樣弄呢…others被當成一個項目加尾端了
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | others = ['Tom','Curry'] |
3 | names.extend(others) |
4 | print(names) |
5 | |
6 | ---------執行結果--------- |
7 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', 'Tom', 'Curry'] |
喔喔使用extend()
救解決了這個問題
取代
那如果names第二個要改成Faker要怎麼取代呢?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | names[1] = 'Faker' |
3 | print(names) |
4 | |
5 | ---------執行結果--------- |
6 | ['Mike', 'Faker', 'Tim', 'Amy', 'Jenny'] |
有了John被改成我們要的Faker了
刪除
那怎麼刪除人名呢?
有三種方法,我們來刪除Amy。
1 | |
2 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
3 | |
4 | # 三種方法delete |
5 | |
6 | # 1. names.remove("Amy") |
7 | # 2. del names[3] |
8 | # 3. names.pop(3) |
9 | |
10 | names.pop(3) #使用pop() |
11 | print(names) |
12 | |
13 | ---------執行結果--------- |
14 | ['Mike', 'John', 'Tim', 'Jenny'] |
- remove():
如果不確定該項目的index,就可以使用remove(value)
的方式來刪除。 - del:
del 是python 的陳述式,並不是list內建的 function,如果要刪除的項目是最後一個,del會釋出list物件的記憶體。 - pop():
使用該項目的index做移除,如果沒有index,default為-1。
尋找index
如果我想知道 Jenny的index是多少該怎麼辦呢?
我們可以這樣寫:
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | |
4 | print(names.index('Jenny')) |
5 | |
6 | ---------執行結果--------- |
7 | 4 |
恩!Jenny真的在[4]。
複製
我們想要複製一個list
首先來看 “ = “ 指派的方法:
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | new = names |
4 | print(names) |
5 | print(new) |
6 | |
7 | ---------執行結果--------- |
8 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
9 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
嗯嗯 如我們預期 new 的值跟 names 一樣。
如果我們更改 names 的值,new 會是如何?
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | new = names |
4 | |
5 | names[0] = 'Faker' |
6 | |
7 | print(names) |
8 | print(new) |
9 | |
10 | ---------執行結果--------- |
11 | ['Faker', 'John', 'Tim', 'Amy', 'Jenny'] |
12 | ['Faker', 'John', 'Tim', 'Amy', 'Jenny'] |
奇怪!我們只是更動了 names,結果 new 也更著改動了。
原因是 用 “ = “ new 只是 reference names同樣的list ,
所以 new 和 names 是用同一個list。
我們看以下 code,new 和 names 的address
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | new = names |
4 | print("names: ",id(names)) |
5 | print("new: ",id(new)) |
6 | |
7 | ---------執行結果--------- |
8 | names: 140348091144264 |
9 | new: 140348091144264 |
是一樣的!
C 語言中 variable 是一個名稱並賦予一個 memmory address
Python 卻是一個指向某個address 的 pointer下圖為 Python variable 概念圖
那怎麼獲得一個獨立的list?
有三種方式
- .copy()
- list()轉換
- slice[:]
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
2 | |
3 | new1 = names.copy() |
4 | new2 = list(names) |
5 | new3 = names[:] |
6 | |
7 | names[0] = 'Faker' |
8 | |
9 | print(names) |
10 | print(new1) |
11 | print(new2) |
12 | print(new3) |
13 | |
14 | ---------執行結果--------- |
15 | ['Faker', 'John', 'Tim', 'Amy', 'Jenny'] |
16 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
17 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
18 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny'] |
大功告成!
如果list中再加入一個list看看……
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny',['GGG','zzz']] |
2 | new = names.copy() |
3 | |
4 | names[5][0] = 'Love' |
5 | new[0] = 'Jake' |
6 | |
7 | print(names) |
8 | print(new) |
9 | |
10 | ---------執行結果--------- |
11 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', ['Love', 'zzz']] |
12 | ['Jake', 'John', 'Tim', 'Amy', 'Jenny', ['Love', 'zzz']] |
奇怪? new 的第二層list怎麼跟著改變了,’GGG’也變成’Love’。
這個叫做 shallow copy
,所謂的 shallow copy
就是只複製記憶體裡位置第一層的列表,而第二層還是有個指標指著同一個object。如下圖:
所以當 names 更改第二層 list ,new 也會跟著更改。
我們來看是不是這樣:1
names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny',['GGG','zzz']]
2
new = names.copy()
3
4
# 更改 第一個元素
5
names[0]= 'xxxx'
6
7
print(id(names[0]))
8
print(id(new[0]))
9
10
#更改第二層 list
11
names[5][0] = 'love'
12
print(id(names[5]))
13
print(id(new[5]))
14
15
---------執行結果---------
16
24274016
17
19899808
18
19
24282136
20
24282136
真的是如此。
喔對了! 我發現,當我還沒更改 names[0]時,兩者第一個元素的 id 是一樣,可見 Python 等到更改時,才生一個新的address 給 new[0]。
那怎麼 copy 整份 list 呢?
我們可以使用 deep copy
, import copy 模組。
1 | import copy |
2 | |
3 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny',['GGG','zzz'],'gogoro'] |
4 | |
5 | new = copy.deepcopy(names) |
6 | |
7 | print(names) |
8 | print(new) |
9 | |
10 | print('---- 更改後 -----') |
11 | |
12 | names[5][0] = 'Love' |
13 | new[0] = 'Lala' |
14 | |
15 | print(names) |
16 | print(new) |
17 | ---------執行結果--------- |
18 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', ['GGG', 'zzz'], 'gogoro'] |
19 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', ['GGG', 'zzz'], 'gogoro'] |
20 | ---- 更改後 ----- |
21 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', ['Love', 'zzz'], 'gogoro'] |
22 | ['Lala', 'John', 'Tim', 'Amy', 'Jenny', ['GGG', 'zzz'], 'gogoro'] |
完成了!!
但大多數情況下,不需要獨立複製一份,如果當列表夠大時,做了deepcoy()會很占記憶體空間。
排序
Python 排序的是由小到大。
Python 提供兩個 function 供我們做排序:
- sort(): 是 list function, 會就地排序 list 本身,也就是會更改原本的 list。
- sorted(): 是通用 function ,會排序list,並 return copy list,不更改原來的 list。
1 | names = ['Mike', 'John', 'Tim', 'Amy', 'Jenny','gogoro'] |
2 | print('--- sort() ----') |
3 | names.sort() |
4 | print(names) |
5 | |
6 | print('--- sorted() ---') |
7 | names2 = ['Mike', 'John', 'Tim', 'Amy', 'Jenny','gogoro'] |
8 | new = sorted(names2) |
9 | print(names2) |
10 | print(new) |
11 | ---------執行結果--------- |
12 | --- sort() ---- |
13 | ['Amy', 'Jenny', 'John', 'Mike', 'Tim', 'gogoro'] |
14 | --- sorted() --- |
15 | ['Mike', 'John', 'Tim', 'Amy', 'Jenny', 'gogoro'] |
16 | ['Amy', 'Jenny', 'John', 'Mike', 'Tim', 'gogoro'] |
呼~~~ 終於結束了