Shopping Cart

購物車內沒有任何商品。

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

一、前言

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

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

立即訂閱電子報,掌握最新資訊!

    稱呼

    電子郵件

    以下非必填,但若您願意分享,我們將能推送更精準的內容給您

    投資經驗

    是否為理工科背景、工程師或有寫程式的經驗?

    有興趣的主題
    量化交易台股期貨海外期貨虛擬貨幣美股

    有興趣的量化交易軟體/平台
    不清楚MultiChartsTradingViewPythonXQ

    想透過量化交易達成甚麼目的?
    不確定自動交易選股回測投資績效量化自己的投資方法想找現成的策略套用

    還有什麼想詢問的?

    20241111 1920 400
    20241111 978 258


    二、快速複習 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社群量化交易討論群」無壓力討論與分享!

    加入Discord 「量化交易討論群」即時獲取實用的資源!

    Write Together 101306261122
    Write Together 101306261121

    QP66
    QP66

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

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

    文章: 24

    發佈留言

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