那曲檬骨新材料有限公司

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

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

3天內不再提示

詳解Python中兩種實現循環的關鍵字

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

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

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

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 循環相比 while 要快 1.5 秒。

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

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

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

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

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 循環的執行效率。

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

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

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 替代循環之后,代碼的執行效率實現了成倍的增長。

內置函數 sum 的累加操作實際上也是一種循環,但它由 C 語言實現,而 for 循環中的求和操作是由純 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 的執行時間約為 2.4e-6,縮短了上百萬倍。這里的思路就是,既然循環的效率低,一段代碼要重復執行上億次。

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

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

實現循環的最快方式—— —— ——就是不用循環

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

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

    關注

    8

    文章

    5375

    瀏覽量

    127058
  • 代碼
    +關注

    關注

    30

    文章

    4825

    瀏覽量

    69043
  • python
    +關注

    關注

    56

    文章

    4807

    瀏覽量

    85037
收藏 人收藏

    評論

    相關推薦

    C語言關鍵字分別發生在哪個階段

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

    Python多線程和多進程的區別

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

    噪聲傳導的兩種模式

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

    C語言關鍵字--typedef

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

    Linux應用層控制外設的兩種不同的方式

    眾所周知,linux下一切皆文件,那么應用層如何控制硬件層,同樣是通過 文件I/O的方式來實現的,那么應用層控制硬件層通常有兩種方式。
    的頭像 發表于 10-05 19:03 ?702次閱讀
    Linux應用層控制外設的<b class='flag-5'>兩種</b>不同的方式

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

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

    typedef struct和直接struct的區別

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

    wdm設備的兩種傳輸方式

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

    快速掌握C語言關鍵字

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

    控制器有哪兩種實現方式?各有何優缺點?

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

    伺服電機與步進電機|兩種電機的關鍵區別

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

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

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

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

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

    淺析多晶硅錠位錯存在的兩種來源

    根據晶體凝固生長與位錯形成、運動與增殖的理論,多晶硅錠位錯存在兩種來源:原生和增殖。
    的頭像 發表于 03-27 11:09 ?614次閱讀
    淺析多晶硅錠<b class='flag-5'>中</b>位錯存在的<b class='flag-5'>兩種</b>來源

    verilogfunction和task的區別

    在Verilog,Function和Task是用于模塊化設計和重用代碼的兩種重要元素。它們允許開發人員將復雜的操作分解為更小的功能單元,并在需要時調用它們。雖然Function和Task在某些方面
    的頭像 發表于 02-22 15:40 ?2034次閱讀
    KTV百家乐官网的玩法技巧和规则| 百家乐怎样概率大| 宝马会百家乐娱乐城| 盈乐博娱乐城| 百家乐官网娱乐送白菜| 叶氏百家乐平注技巧| 新皇冠娱乐城| 网络赌博游戏| 百家乐实时路单| 大发888检测技能| 百家乐官网破解仪恒达| 百家乐博赌场娱乐网规则| 高州市| 国际百家乐规则| bet365提款要多久| 678百家乐官网博彩娱乐平台 | 百家乐免佣台| 姚记娱乐城官网| 百家乐官网黏土筹码| 大发888手机好玩吗| 视频百家乐官网赢钱| 淘宝博百家乐的玩法技巧和规则| 博狗百家乐官网现场| 老k百家乐游戏| 鹿泉市| 百家乐生活馆| 澳门百家乐官网海星王| 怎么看百家乐路单| 百家乐官网分析资料| 百家乐博娱乐场| 百家乐官网视频计牌器| 什么事百家乐的路单| 免费百家乐官网在线| 澳门百家乐怎么下载| 澳门百家乐官网如何算| 棋牌游戏开发商| 淘金百家乐官网的玩法技巧和规则 | 百家乐模拟投注器| 沙龙娱乐| 真人百家乐视频赌博| 百家乐官网视频麻将游戏|