iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0

快速宣告

結合 list()range() 可以快速產生連續元素的列表:

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

也可以在 range() 裡面指定進階參數:

>>> list(range(7, 23, 3))
[7, 10, 13, 16, 19, 22]

負索引值

如果要取得列表的第一個元素,可以指定 arr[0],那如果要取得最後幾個元素呢?可以使用負數索引值:

>>> arr = list(range(10))
>>> arr[0], arr[1], arr[-1], arr[-2]
(0, 1, 9, 8)

arr[-1] 就是倒數第一個元素,arr[-2] 就是倒數第二個元素。

切片

當我們想要從列表中取出一份子列表時,可以利用切片 (Slice) 語法:

>>> arr = list(range(10))
>>> arr[3:7]
[3, 4, 5, 6]

arr[3:7] 代表從索引值為 3 的元素開始,一路取到索引值 7 之前,但是不包含 7,因此取出了 3, 4, 5, 6 等四個元素。也可以跳著取:

>>> arr[2:8:2]
[2, 4, 6]

arr[2:8:2] 代表從索引值 2 開始取到索引值 8 之前,並且每 2 個取一次,因此 3, 5, 7 被跳過,只留下 2, 4, 6 等。

第一個數字跟第二個數字可以留白,如果沒有指定第一個數字,代表從開頭開始取;如果沒有指定第二個數字,代表取到列表的結尾:

>>> print(arr[:7])  # 取到 7 之前
>>> print(arr[3:])  # 從 3 開始取
>>> print(arr[::])  # 都不給,純炫技?
[0, 1, 2, 3, 4, 5, 6]
[3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

兩個都不給的話,就是原本的列表,乍看之下好像純為炫技?其實不然,當我們將列表直接指定給其他變數時,彼此之間的修改會互相影響:

>>> arr1 = list(range(10))
>>> arr2 = arr1
>>> arr2[1] = -1
>>> print(arr1)
>>> print(arr2)
[0, -1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, -1, 2, 3, 4, 5, 6, 7, 8, 9]

一開始將 arr1 指定給 arr2,當 arr2 被修改時,連 arr1 也一同被修改掉。這其實與一般的整數變數行為並不相同:

>>> a = 5
>>> b = a
>>> b += 1
>>> a, b
(5, 6)

可以看到,一樣是把 a 指定給 b,但是修改 b 變數並不會導致 a 也被修改。這是因為列表屬於可變的 (Mutable) 物件,而整數屬於不可變的 (Immutable) 的資料。

所謂的可變與不可變指的是變數的內容在記憶體裡面的狀態。當一個列表被紀錄在記憶裡面時,他的內容、長度都是可以修改的,因此被稱為可變的。而整數看起來似乎也能修改,但其實變數 b 從 5 變成 6 的過程中,是 b 變成了 6,而不是 5 變成 6,系統會創造一個新的整數放到 b 裡面,所以整數、浮點數等被稱為不可變的

物件為可變或不可變的性質,對其參數傳遞、賦值複製等行為有很大的影響。因為可變的物件通常很大,一個列表可能有成千上萬個數值,若是每次都複製成不同列表,會對記憶體造成很大的負擔,因此預設是不複製列表的,而是讓變數們都指向同一塊記憶體。當我們想要複製列表時,就可以透過切片的技巧來達成:

>>> arr1 = list(range(10))
>>> arr2 = arr1[::]
>>> arr2[1] = -1
>>> print(arr1)
>>> print(arr2)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, -1, 2, 3, 4, 5, 6, 7, 8, 9]

這樣修改 arr2 時,就不會影響到 arr1 了。其實可以直接用一個冒號 arr1[:] 就好,寫兩個冒號只是我的習慣 🤣

切片賦值

切片除了能放在賦值右邊,也能放在賦值左邊:

>>> arr1 = list(range(10))
>>> print(arr1)
>>>
>>> arr1[5:] = [10, 20, 30, 40, 50]
>>> print(arr1)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 10, 20, 30, 40, 50]

自我練習

  1. 寫一個函式 odd_pow() 傳入一個列表,將索引值為奇數的元素挑出來,計算他的平方再回傳。
  2. 第一題的做法並不會使傳入的列表內容被修改,嘗試用切片賦值的技巧,修改原本列表的內容。

完整的程式碼放在此 Colab 裡面供各位參考。


上一篇
如何增刪列表的元素?
下一篇
索引值不一定要是整數
系列文
From Python Beginner To AI Engineer31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言