原來選取資料可以這麼有效!帶你快速瞭解 Python range() 的「:: 雙冒號」是什麼?

學.誌|Chris Kang
4 min readNov 19, 2019

--

說明一下在進行一些區間的資料選擇時,如果擁有特定規律,那 Slicing 的技巧絕對能省下你很多時間。

這篇文章會詳細說明 Python 裡 range 的使用方式,以及 [] 的資料切片工具,以及其中的概念。那麼,就開始吧!

Range 的用法

第一個部分,先從 range 的概念說起。其實 range 就是一個整數產生器,但能夠以較少的記憶體產生連續的數列,亦即能讓程式運行較快。

其中的關鍵概念為––––我們能夠設定他的開始、結束,以及間距,個別使用一個參數來設定。要特別注意的是, range 也能設定負整數,例如 range(-10, -1, 2) 等,如果設定無法產生的 list,則會產生空的 list。

參數設定

  1. X|欲設定起始的整數,預設為 0
  2. Y|欲設定結束的整數前(亦即設定 5 則只會到 4)
  3. Z|數列之間的數字差距(亦即公差),預設為 1

設定規則

# 公式說明
>>> range(x, y, z)
  • 一個參數:默認為 Y ,而 X 則預設為從 0 開始,Z 預設為 1
  • 兩個參數:被辨識為 X、Y,Z 預設為 1
  • 三個參數:按照上述規則運行
# 實際範例演示>>> range(6)
[1, 2, 3, 4, 5]
>>> range(1,5)
[1, 2, 3, 4]
>>> range(1,7,2)
[1, 3, 5]

切片(Slicing)的應用:

雖然這個功能很好用,但要注意使用 slicing 時,並不適用於 built-in list、tuple 和 string sequence,系統會跑出 TypeError。

核心概念與參數

# 示範用數列 
a = range(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 表示 a[i] 複製到 a[j-1],以 k 的間距取樣
b = a[i:j:k]

用法說明

# 一般參數用法
>>> b = a[1:5:1] # 與 a[1:5] 的 OUTPUT 相同
>>> b
[1,2,3,4]
---------------# 當沒有 i 的參數時,就預設為 0,亦即從頭開始
>>> a[:3] # 相當於 a[0:3]
# 當沒有 j 的參數時,就預設為 len(a),亦即到數列結束
>>> a[1:] # 相當於 a[1:10]
# 當沒有 i,j,k 時,就相當於完整複製一份 a 的 list
>>> a[:]
>>> a[::] # 兩者效果相同
------------# 當沒有 k 時,預設為 1,亦即設定公差為一
>>> a[1:5]
[1,2,3,4]
# 當有設定 k 時,就會依照該間距來取樣,會從第一個開始取樣
>>> a[2:7:2]
[2, 4, 6]

其中有個特別的用法,當參數 k 為負整數時,該 list 就會從後面算過來。是因為在 Python 裡,list 的 index 有兩種,一種是常見的 [0, 1, 2,… , len(list)-1],另一種則是 [-len(list), …, -2, -1] 倒著數過來的 list。

換句話說,如果 k 設定為 -1,該數列就會從最後一個開始計算,直到該 list 的開頭。下面就用實例來說明:

# 除了最后一個取全部
>>>(a[:-1])
[0, 1, 2, 3, 4, 5, 6, 7, 8]
# 當 k < 0 時,i 默認為 -1,j 默認為 -len(list)
>>> c = a[::-1]
[9,8,7,6,5,4,3,2,1,0]
# 從標籤為 2 (亦即[0,1,2,..] 的參數選取下) 的 list 下反向呈現
>>> a[2::-1]
[2, 1, 0]
# 選取到標籤為 5 的 list 並反向呈現
>>> d= a[:5:-2]
[9, 7]

這些用法在進行等差的資料選取時,能夠發揮意想不到的功能,以此篇作為一個記錄,也同時提醒自己別忘了這個方便的功能。

謝謝你/妳,願意把我的文章閱讀完

如果你喜歡筆者在 Medium 的文章,可以拍個手(Claps),最多可以按五個喔!也歡迎你分享給你覺得有需要的朋友們。

參考文獻:

--

--

學.誌|Chris Kang
學.誌|Chris Kang

Written by 學.誌|Chris Kang

嗨!我是 Chris,一位擁有技術背景的獵頭,熱愛解決生活與職涯上的挑戰。專注於產品管理/資料科學/前端開發 / 人生成長,在這條路上,歡迎你找我一起聊聊。歡迎來信合作和交流: chriskang0917@gmail.com

Responses (1)