Python 理財程式小技巧 – 一行程式碼就把 for 迴圈搞定

一、前言

迴圈是每種程式語言必學的語法,迴圈可以把重複的行為包在同一段程式碼裡,讓程式碼看起來變得更精簡、容易維護。實際上,Python 還有一個大招讓程式碼更漂亮:一行程式碼就把 for 迴圈搞定,把迴圈取用的內容存成 list 或 dict 字典。

這是成為 Python 高手必學的技巧之一!當你的專案越來越龐大,程式碼越來越複雜,讓程式碼瘦身可以大幅加強維護效率。

好富投 1920x400
好富投 978x258

點我了解更多資訊


二、快速複習 for 迴圈的用法

假設我們現在想要把 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 當中。

Py 101209161710
Py 101209161711

三、單行 for 迴圈製作 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 迴圈製作 dict

單行 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 理財程式小技巧 – 優化程式執行速度,從減少重複索引龐大數據和向量化做起》這篇有提過。有興趣的同學可以思考並自行撰寫看看。

大家一起來成為 Python 高手吧!


量化通粉絲社群,一起討論程式交易!

加入LINE社群量化交易討論群」無壓力討論與分享!

加入臉書社團「程式交易 Taiwan」即時獲取實用的資源!

QP66
QP66

具備逾十年交易經驗,研究交易資產橫跨股票、債券、外匯、原物料,以及加密貨幣。現為量化避險基金交易員,亦曾任職於資金規模逾百億的避險基金,以及在區塊鏈企業擔任顧問一職。

擅長從宏觀至微觀,由淺入深挖掘交易機會,並運用Python實現全自動化的投資組合管理。

文章: 24

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *