0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

詳解Python中兩種實現循環(huán)的關鍵字

python爬蟲知識分享 ? 來源:python爬蟲知識分享 ? 作者:python爬蟲知識分享 ? 2022-03-25 16:04 ? 次閱讀

眾所周知,Python 不是一種執(zhí)行效率較高的語言。此外在任何語言中,循環(huán)都是一種非常消耗時間的操作。假如任意一種簡單的單步操作耗費的時間為 1 個單位,將此操作重復執(zhí)行上萬次,最終耗費的時間也將增長上萬倍。

whilefor 是 Python 中常用的兩種實現循環(huán)的關鍵字,它們的運行效率實際上是有差距的。比如下面的測試代碼:

import timeit


def while_loop(n=100_000_000):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s

def for_loop(n=100_000_000):
    s = 0
    for i in range(n):
        s += i
    return s

def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=1))
    print('for loop\t\t', timeit.timeit(for_loop, number=1))

if __name__ == '__main__':
    main()
# => while loop               4.718853999860585
# => for loop                 3.211570399813354

這是一個簡單的求和操作,計算從 1 到 n 之間所有自然數的總和。可以看到 for 循環(huán)相比 while 要快 1.5 秒。

其中的差距主要在于兩者的機制不同。

在每次循環(huán)中,while 實際上比 for 多執(zhí)行了兩步操作:邊界檢查和變量 i 的自增。即每進行一次循環(huán),while 都會做一次邊界檢查 (while i < n)和自增計算(i +=1)。這兩步操作都是顯式的純 Python 代碼。

for 循環(huán)不需要執(zhí)行邊界檢查和自增操作,沒有增加顯式的 Python 代碼(純 Python 代碼效率低于底層的 C 代碼)。當循環(huán)的次數足夠多,就出現了明顯的效率差距。

可以再增加兩個函數,在 for 循環(huán)中加上不必要的邊界檢查和自增計算:

import timeit


def while_loop(n=100_000_000):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s

def for_loop(n=100_000_000):
    s = 0
    for i in range(n):
        s += i
    return s

def for_loop_with_inc(n=100_000_000):
    s = 0
    for i in range(n):
        s += i
        i += 1
    return s

def for_loop_with_test(n=100_000_000):
    s = 0
    for i in range(n):
        if i < n:
            pass
        s += i
    return s

def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=1))
    print('for loop\t\t', timeit.timeit(for_loop, number=1))
    print('for loop with increment\t\t',
          timeit.timeit(for_loop_with_inc, number=1))
    print('for loop with test\t\t', timeit.timeit(for_loop_with_test, number=1))

if __name__ == '__main__':
    main()
# => while loop               4.718853999860585
# => for loop                 3.211570399813354
# => for loop with increment          4.602369500091299
# => for loop with test               4.18337869993411

可以看出,增加的邊界檢查和自增操作確實大大影響了 for 循環(huán)的執(zhí)行效率。

前面提到過,Python 底層的解釋器和內置函數是用 C 語言實現的。而 C 語言的執(zhí)行效率遠大于 Python。

對于上面的求等差數列之和的操作,借助于 Python 內置的 sum 函數,可以獲得遠大于 forwhile 循環(huán)的執(zhí)行效率。

import timeit


def while_loop(n=100_000_000):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s

def for_loop(n=100_000_000):
    s = 0
    for i in range(n):
        s += i
    return s

def sum_range(n=100_000_000):
    return sum(range(n))

def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=1))
    print('for loop\t\t', timeit.timeit(for_loop, number=1))
    print('sum range\t\t', timeit.timeit(sum_range, number=1))

if __name__ == '__main__':
    main()
# => while loop               4.718853999860585
# => for loop                 3.211570399813354
# => sum range                0.8658821999561042

可以看到,使用內置函數 sum 替代循環(huán)之后,代碼的執(zhí)行效率實現了成倍的增長。

內置函數 sum 的累加操作實際上也是一種循環(huán),但它由 C 語言實現,而 for 循環(huán)中的求和操作是由純 Python 代碼 s += i 實現的。C > Python。

再拓展一下思維。小時候都聽說過童年高斯巧妙地計算 1 到 100 之和的故事。1…100 之和等于 (1 + 100) * 50。這個計算方法同樣可以應用到上面的求和操作中。

import timeit


def while_loop(n=100_000_000):
    i = 0
    s = 0
    while i < n:
        s += i
        i += 1
    return s

def for_loop(n=100_000_000):
    s = 0
    for i in range(n):
        s += i
    return s

def sum_range(n=100_000_000):
    return sum(range(n))

def math_sum(n=100_000_000):
    return (n * (n - 1)) // 2

def main():
    print('while loop\t\t', timeit.timeit(while_loop, number=1))
    print('for loop\t\t', timeit.timeit(for_loop, number=1))
    print('sum range\t\t', timeit.timeit(sum_range, number=1))
    print('math sum\t\t', timeit.timeit(math_sum, number=1))

if __name__ == '__main__':
    main()
# => while loop               4.718853999860585
# => for loop                 3.211570399813354
# => sum range                0.8658821999561042
# => math sum                 2.400018274784088e-06

最終 math sum 的執(zhí)行時間約為 2.4e-6,縮短了上百萬倍。這里的思路就是,既然循環(huán)的效率低,一段代碼要重復執(zhí)行上億次。

索性直接不要循環(huán),通過數學公式,把上億次的循環(huán)操作變成只有一步操作。效率自然得到了空前的加強。

最后的結論(有點謎語人):

實現循環(huán)的最快方式—— —— ——就是不用循環(huán)

對于 Python 而言,則盡可能地使用內置函數,將循環(huán)中的純 Python 代碼降到最低。
審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 測試
    +關注

    關注

    8

    文章

    5316

    瀏覽量

    126722
  • 代碼
    +關注

    關注

    30

    文章

    4791

    瀏覽量

    68694
  • python
    +關注

    關注

    56

    文章

    4797

    瀏覽量

    84756
收藏 人收藏

    評論

    相關推薦

    C語言關鍵字分別發(fā)生在哪個階段

    以下C語言關鍵字,分別發(fā)生在哪個階段? 第一個,define。 首先得糾正一下,define 并不是C語言里面的關鍵字,即使加了井號,也不是。 define 屬于C語言的預處理指令,很顯然,它發(fā)生
    的頭像 發(fā)表于 11-24 10:31 ?191次閱讀

    Python多線程和多進程的區(qū)別

    Python作為一高級編程語言,提供了多種并發(fā)編程的方式,其中多線程與多進程是最常見的兩種方式之一。在本文中,我們將探討Python多線
    的頭像 發(fā)表于 10-23 11:48 ?411次閱讀
    <b class='flag-5'>Python</b><b class='flag-5'>中</b>多線程和多進程的區(qū)別

    噪聲傳導的兩種模式

    噪聲傳導有兩種模式,一為差模傳導,一為共模傳導。
    的頭像 發(fā)表于 10-15 11:33 ?311次閱讀
    噪聲傳導的<b class='flag-5'>兩種</b>模式

    C語言關鍵字--typedef

    C語言關鍵字使用方法學習指南!
    的頭像 發(fā)表于 10-07 12:44 ?276次閱讀

    使用邊緣AI和Sitara處理器進行關鍵字檢測

    電子發(fā)燒友網站提供《使用邊緣AI和Sitara處理器進行關鍵字檢測.pdf》資料免費下載
    發(fā)表于 09-02 11:30 ?0次下載
    使用邊緣AI和Sitara處理器進行<b class='flag-5'>關鍵字</b>檢測

    typedef struct和直接struct的區(qū)別

    在C語言中, typedef 和 struct 是兩種不同的關鍵字,它們在定義和使用上有著明顯的區(qū)別。 typedef struct 和直接 struct 在 C 語言中用于定義結構體類型,但它們在
    的頭像 發(fā)表于 08-20 10:58 ?2821次閱讀

    wdm設備的兩種傳輸方式

    系統,有多種傳輸方式,其中最常見的兩種是密集波分復用(DWDM)和粗波分復用(CWDM)。 1. 密集波分復用(DWDM) 1.1 DWDM技術原理 密集波分復用(Dense Wavelength Division Multiplexing,簡稱DWDM)是一
    的頭像 發(fā)表于 07-18 09:45 ?496次閱讀

    快速掌握C語言關鍵字

    C語言中的32個關鍵字你知道多少個呢?根據關鍵字的作用分為四類:數據類型關鍵字、控制語句關鍵字、存儲類型關鍵字和其它
    的頭像 發(fā)表于 07-06 08:04 ?358次閱讀
    快速掌握C語言<b class='flag-5'>關鍵字</b>

    控制器有哪兩種實現方式?各有何優(yōu)缺點?

    控制器是計算機系統的一個關鍵組件,負責協調和管理計算機硬件和軟件資源。在不同的應用場景和系統,控制器的實現方式可能會有所不同。以下是兩種
    的頭像 發(fā)表于 06-30 10:33 ?1325次閱讀

    伺服電機與步進電機|兩種電機的關鍵區(qū)別

    ? ? ? 在自動化控制的世界,伺服電機和步進電機是實現精準動力傳輸的關鍵角色。雖然它們的終極目標相同,即精確控制機械運動,但它們的工作原理和最佳應用場景卻有所不同。本文將帶你了
    的頭像 發(fā)表于 06-17 16:21 ?912次閱讀
    伺服電機與步進電機|<b class='flag-5'>兩種</b>電機的<b class='flag-5'>關鍵</b>區(qū)別

    PCBA加工中常見的兩種焊接方式詳解

    一站式PCBA智造廠家今天為大家講講PCBA加工手工焊接有哪幾種方式?PCBA加工過程中常用焊接方式。在PCBA(印刷電路板組裝)加工過程,焊接是一個關鍵的步驟。而手工焊接作為一常見的焊接方式
    的頭像 發(fā)表于 06-14 09:18 ?557次閱讀

    溫度沖擊與溫度循環(huán):揭示材料失效的兩種溫度試驗方法

    溫度沖擊試驗與溫度循環(huán)試驗,雖然都是對材料或產品進行溫度應力測試的方法,但它們的應力負荷機理存在顯著差異。簡單來說,溫度沖擊主要關注蠕變及疲勞損傷導致的失效,而溫度循環(huán)則更多地考察由剪切疲勞所引發(fā)的失效。這兩種試驗在試驗環(huán)境、取
    的頭像 發(fā)表于 04-18 15:07 ?1023次閱讀
    溫度沖擊與溫度<b class='flag-5'>循環(huán)</b>:揭示材料失效的<b class='flag-5'>兩種</b>溫度試驗方法

    關鍵字搜索文件夾某個TXT文件

    文件夾隨時創(chuàng)造TXT文件,如何及時選出剛創(chuàng)造的文件?或關鍵字搜索出需要的TXT文件?
    發(fā)表于 02-06 15:22

    異或門兩種常見的實現方式

    兩種實現方式都能夠實現異或門的功能,具體的選擇取決于設計需求和邏輯門的可用性。實際構建異或門時,可以使用離散電子元件(如晶體管、二極管等)或整合電路芯片(如 TTL、CMOS 等)來實現
    的頭像 發(fā)表于 02-04 17:30 ?1.3w次閱讀
    異或門<b class='flag-5'>兩種</b>常見的<b class='flag-5'>實現</b>方式

    在NVM和本地\"內存定義數組(靜態(tài) /global /local)的\"關鍵字是什么?

    在 NVM 和本地\"內存定義數組(靜態(tài) /global /local)的\"關鍵字是什么? 還有與 32 位對齊的關鍵字怎么樣。
    發(fā)表于 01-25 07:52