- 登入
- 註冊
迴圈是每種程式語言必學的語法,迴圈可以把重複的行為包在同一段程式碼裡,讓程式碼看起來變得更精簡、容易維護。實際上,Python 還有一個大招讓程式碼更漂亮:一行程式碼就把 for 迴圈搞定,把迴圈取用的內容存成 list 或 dict 字典。
這是成為 Python 高手必學的技巧之一!當你的專案越來越龐大,程式碼越來越複雜,讓程式碼瘦身可以大幅加強維護效率。
假設我們現在想要把 2015 年 1 月 1 日至 2021 年 12 月 31 日期間所有平日開盤時間取出來。例如 2015-01-07 09:00:00 屬於會被取出來的時間日期,而 2015-01-07 13:31:00 已經收盤了,不會被取出來。
我們為了舉例方便,姑且先不管平日放假、周末補班開市的情形。使用一般迴圈寫法的程式碼如下:
from datetime import datetime, time
import pandas as pd
date_range = pd.date_range(datetime(2015,1,1),datetime(2021,12,31,13,30,0), freq="1T")
opening_time = []
for i in date_range:
if (i.time() >= time(9,0,0)
and i.time() <= time(13,30,0)
and i.weekday() not in [5,6]
):
opening_time.append(i)
這裡稍微解釋一下程式碼:
首先,我們使用 pd.date_range 建立自 2015-01-01 至 2021-12-31 期間每一分鐘的 pandas Timestamp 的 DatetimeIndex。Timestamp 用法基本上和 datetime 相同,DatetimeIndex 可以和 list 一樣用 for 迴圈把元素逐一取出來使用。
接著,把 date_range 用 for 迴圈把每個元素逐一取出來,判斷它的時間是否在 9:00 ~ 13:30 之間,並且它不是星期六和星期日。只要符合條件的元素,就塞進 opening_time 這個 list 當中。
接著,我們該如何用一行程式碼寫出跟上面一樣的 for 迴圈呢?
# 語法一:
變數名稱 = [
每圈想存入的元素
for 每圈取出的元素 in 清單 if 條件式
]
# 語法二:
變數名稱 = [
條件式為 True 時存入的值 if 條件式 else條件式為 False 時存入的值
for 每圈取出的元素 in 清單
]
以上兩種語法皆可使用。if else 不一定需要定義,若沒定義條件式,就只是單純每一個迴圈把元素取出來,不加上過濾條件罷了。另外,為了排版需求,我們把內容做一點斷行。
我們直接以先前的例子做舉例:
from datetime import datetime, time
date_range = pd.date_range(datetime(2015,1,1),datetime(2021,12,31,13,30,0), freq="1T")
opening_time = [
i for i in date_range
if i.time() >= time(9,0,0)
and i.time() <= time(13,30,0)
and i.weekday() not in [5,6]
]
紅字的部分即為單行 for 迴圈的程式碼。我們每一圈都從 date_range 中取出一個元素 i,並判斷是否在 9:00 ~ 13:30 之間且非週六和週日。如果符合條件,則把 i 存入這個 list 之中。
單行 for 迴圈能做的不只是創建 list,創建字典也可以用一樣的語法:
變數名稱 = {
每圈想存入的索引: 每圈想存入索引下對應的值
for 每圈取出的元素 in 清單 if 條件式
}
延續先前的例子,假設我們現在要把剛剛取出的時間日期當作索引,索引底下對應的值是星期,0 表示週一、1 表示週二,以此類推。我們可以用下方的寫法:
opening_time = {
i:i.weekday() for i in date_range
if i.time() >= time(9,0,0)
and i.time() <= time(13,30,0)
and i.weekday() not in [5,6]
}
如此,簡潔明瞭的程式碼就輕易地完成了!
實際上,當初學者熟練這個用法之後,就可以更進階把 for 迴圈每次取出兩個元素的寫法應用進來,例如 dict.items() 等,可以完美迴避掉 for 迴圈內哪兒忘記寫 append、哪兒漏了判斷式的問題!
另外,其實剛剛的範例,有個向量化的寫法可以稍微加速運算效率,在《Python 理財程式小技巧 – 優化程式執行速度,從減少重複索引龐大數據和向量化做起》這篇有提過。有興趣的同學可以思考並自行撰寫看看。