python 列表的切片和賦值操作很基礎,之前也遇到過一些坑,以為自己很懂了。但今天刷 codewars 時發現了乙個更大的坑,故在此記錄。
python 列表賦值:複製「值」還是「引用」?
很多入門 python 的人會犯這樣乙個錯誤:在賦值操作=中搞不清是賦了「值」還是「引用」。比如:
a =[1
,2,3
]b = ab[0
]=10# 更改列表 b 的第乙個元素,但 a 現在也被更改為了 [10, 2, 3]
他可能只想改變列表b,但實際上這樣也會改變列表a。
因為b實際上是列表a的另乙個引用,a和b是同乙個物件,id(a) == id(b)
,所以更改b也會更改a。這個應該大部分人都知道。所以正確的**應該使用切片來進行列表的複製:
'''
'''a =[1
,2,3
]b = a[:]
# 使用切片進行列表複製b[0
]=10# 此時 a 和 b 是兩個不同的物件
二維列表引發的思考:列表的本質
好的,現在我們確定切片能夠進行列表的複製。那我們就能心安理得地改動新的列表了嗎?請看二維列表(二維陣列):
a =[[
1,2,
3],[
4,5,
6]]b = a[:]
b[0][
0]=10
此時,a還是被改動了!
原因是,雖然id(a) == id(b)
為false,a和b確實不是同乙個物件。但它們的元素都是同乙個物件——id(a[0]) == id(b[0])
,id(a[1]) == id(b[1])
。因為列表裡儲存的是物件的引用!
列表 list 終究只是個容器。就像 tuple 本身是 immutable (不可變)的,但它只是容器,它可以儲存乙個可變物件,因此呈現出一種可以被改動的「假象」。例如:
'''
'''>>
> a =([
1],)
>>
> a[0]
[0]=
2>>
> a([
2],)
所以容器和它儲存的物件不能混為一談。所以對於這種二維列表,想要進行完全的複製,請直接使用copy.deepcopy()
深度複製。
如果只想複製一部分(切片),那可以先複製再切片:
>>
>
import copy
>>
> a =[[
1,2,
3],[
4,5,
6],[
7,8,
9]]>>
> b = copy.deepcopy(a)[1
:]>>
> b[0]
[0]=
100>>
> a[[
1,2,
3],[
4,5,
6],[
7,8,
9]]>>
> b[[
100,5,
6],[
7,8,
9]]
此時修改b沒有影響到a。 python 切片 Python 列表切片
想必很多人都使用過列表的切片,通過切片可以從列表中獲取乙個或多個元素,但你真的了解切片?一 一般玩法 name a b c d e f g h name 0 2 獲取 0 2 中間的元素,不包括索引為 2 的元素 a b name 2 從 0 開始切,可省略 0 a b name 1 同樣地,切到最...
python 列表切片
a 0,1,2,3,4,5,6,7,8,9 print a 1 3 a 1 3 print a 3 a 3 print a 3 a 3 print a 1 7 2 a 1 7 2 步長為2 print a 1 a 1 從後往前遍歷 print a 7 1 2 a 7 1 2 從後往前遍歷,步長為2 ...
python列表切片
基本含義 從第i位索引起,向右取到後n位元素為止,按m間隔過濾 基本格式 i i n m i 是切片的起始索引值,為列表首位時可省略 i n 是切片的結束位置,為列表末位時可省略 m 可以不提供,預設值是1,不允許為0,當m為負數時,列表翻轉。注意 這些值都可以大於列表長度,不會報越界。正數索引,預...