挑戰在代碼裡面不寫for迴圈,讓代碼變得更簡潔、規範、結構化,以及更好的代碼可讀性!

来源:https://www.cnblogs.com/hahaa/archive/2022/08/10/16573889.html
-Advertisement-
Play Games

哈嘍兄弟們,又是新的一天!今天你敲代碼了嗎? 一、序言 為什麼要挑戰自己在代碼里不寫 for loop?因為這樣可以迫使你去學習使用比較高級、比較地道的語法或 library。文中以 python 為例子,講了不少大家其實在別人的代碼里都見過、但自己很少用的語法。 自從我開始探索 Python 中驚 ...



哈嘍兄弟們,又是新的一天!今天你敲代碼了嗎?

一、序言

為什麼要挑戰自己在代碼里不寫 for loop?因為這樣可以迫使你去學習使用比較高級、比較地道的語法或 library。文中以 python 為例子,講了不少大家其實在別人的代碼里都見過、但自己很少用的語法。

自從我開始探索 Python 中驚人的語言功能已經有一段時間了。一開始,我給自己一個挑戰,目的是讓我練習更多的 Python 語言功能,而不是使用其他編程語言的編程經驗。這讓事情變得越來越有趣!代碼變得越來越簡潔,代碼看起來更加結構化和規範化。下麵我將會介紹這些好處。

二、正文

通常如下使用場景中會用到 for 迴圈:

  • 在一個序列來提取一些信息
  • 從一個序列生成另一個序列
  • 寫 for 已成習慣

幸運的是,Python 已經有很多工具可以幫助你完成這些工作,你只需要轉移你的思路,並以不同的角度來思考它。

通過避免編寫 for 迴圈,你可以獲得什麼好處:

  • 較少的代碼量
  • 更好的代碼可讀性
  • 更少的縮進(對 Python 還是很有意義的)

我們來看一下下麵的代碼結構:

# 1
with ...:
    for ...:
        if ...:
            try:
            except:
        else:

學習中遇到問題沒人解答?小編創建了一個Python學習交流基地,點擊藍色字體即可,尋找有志同道合的小伙伴,互幫互助,這裡還有不錯的視頻學習教程和PDF電子書!

在這個例子中,我們正在處理多層嵌套的代碼,這很難閱讀。這個例子使用了多層嵌套的代碼。我在這段代碼中發現它無差別使用縮進把管理邏輯(with, try-except)和業務邏輯(for, if)混在一起。如果你遵守只對管理邏輯使用縮進的規範,那麼核心業務邏輯應該立刻脫離出來。

“扁平結構比嵌套結構更好” - The Zen of Python

可以使用的已有的工具來替換 for 迴圈

1.List Comprehension / Generator 表達式

我們來看一個簡單的例子。如果你想將一個數組轉換為另一個數組:

result = []
for item in item_list:
    new_item = do_something_with(item)
    result.append(item)
#Python學習交流群:279199867

 

如果你喜歡 MapReduce,你也可以使用 map,或者 Python 中的 List Comprehension:

result = [do_something_with(item) for item in item_list]

 

同樣,如果您只想迭代數組中的元素,也可以使用一樣的代碼 Generator Expression。result = (do_something_with(item) for item in item_list)

2.函數

如果您想要將一個數組映射成另外數組,只需調用 map 函數,就可以用一個更高級、更實用的編程方式解決這個問題。

doubled_list = map(lambda x: x * 2, old_list)

 

如果要將序列減少為單個,請使用 reduce

from functools import reduce
summation = reduce(lambda x, y: x + y, numbers)

 

另外,許多 Python 內置函數都會使用 iterables:

>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> all(a)
False
>>> any(a)
True
>>> max(a)
9
>>> min(a)
0
>>> list(filter(bool, a))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> set(a)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> dict(zip(a,a))
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
>>> sorted(a, reverse=True)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> str(a)
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'
>>> sum(a)
45

 

3.Extract Functions or Generators

上述兩種方法是很好的處理更簡單的邏輯。更複雜的邏輯怎麼樣?作為程式員,我們編寫函數來抽離出複雜的業務。相同的想法適用於此。如果你是這樣寫的:

results = []
for item in item_list:
    # setups
    # condition
    # processing
    # calculation
    results.append(result)

 

顯然你對一個代碼塊添加了太多的責任。相反,我建議你做:

def process_item(item):
    # setups
    # condition
    # processing
    # calculation
    return result

results = [process_item(item) for item in item_list]

 

如果換成嵌套函數會如何

results = []
for i in range(10):
    for j in range(i):
        results.append((i, j))

 

換成 List Comprehension 來實現是這樣的:

results = [(i, j)
           for i in range(10)
           for j in range(i)]

 

如果你的代碼塊需要記錄一些內部狀態

# finding the max prior to the current item
a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
results = []
current_max = 0
for i in a:
    current_max = max(i, current_max)
    results.append(current_max)

# results = [3, 4, 6, 6, 6, 9, 9, 9, 9, 9]

 

我們使用 generator 來實現這一點:

def max_generator(numbers):
    current_max = 0
    for i in numbers:
        current_max = max(i, current_max)
        yield current_max

a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
results = list(max_generator(a))

 

讀者可能要問 “等等!你在 generator 中用到 for 迴圈,作弊啊!別急,再看看下麵的代碼。

不要自己寫,itertools 會幫你實現了。

這個模塊很簡單。我相信這個模塊在大多數場景中可以替換你原先的 for 迴圈。例如,最後一個例子可以重寫為:

from itertools import accumulate
a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
resutls = list(accumulate(a, max))

 

另外,如果要迭代組合序列,則需要使用product(), permutations(), combinations()。

三、結論

  • 在大多數情況下,您都不需要編寫 for 迴圈。
  • 你應該避免編寫 for 迴圈,這樣會有更好的代碼可讀性。

好了我的兄弟,今天的分享就到這,給大家推薦一套爬蟲視頻,涵蓋90%常見案例,希望對你有所幫助!

爬蟲:Python爬蟲入門到精通100集實戰

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 枚舉和註釋 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 自定義類實現枚舉 先看一個需求 要求創建季節(Season)對象,請設計並完成。 創建Season對象有如下特點 1.季節的值是有限的幾個值(spring, summer, ...
  • 一、分庫分表解決的現狀問題 解決資料庫本身瓶頸 連接數: 連接數過多時,就會出現‘too many connections’的錯誤,訪問量太大或者資料庫設置的最大連接數太小的原因 Mysql預設的最大連接數為100.可以修改,而mysql服務允許的最大連接數為16384 資料庫分表可以解決單表海量數 ...
  • #反射機制 AVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。 Java反射機制在框架設計中極為廣泛,需要深入理解。 ##反射基礎 RTTI(R ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • MySQL之JDBC 一、JDBC是什麼 Java DatabaseConnectivity (java語言連接資料庫) 二、JDBC的本質 JDBC是SUN公司制定的一套介面(interface)。 介面都有調用者和實現者。 面向介面調用、面向介面寫實現類,這都屬於面向介面編程。 三、為什麼要面向 ...
  • 1.認識shiro 除Spring Security安全框架外,應用非常廣泛的就是Apache的強大又靈活的開源安全框架 Shiro,在國內使用量遠遠超過Spring Security。它能夠用於身份驗證、授權、加密和會話管理, 有易於理解的API,可以快速、輕鬆地構建任何應用程式。而且大部分人覺得 ...
  • 面向對象編程(高級) 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 類變數和類方法(static) 類變數 類變數-提出問題 提出問題的主要目的就是讓大家思考解決之道,從而引出我要講的知識點.說:有一群小孩在玩堆雪人,不時有新的小 ...
  • Java常用類(一) 一、String 類:(不可變的字元序列) 1.1 String:字元串,使用一對 " " 引起來表示。 String 類聲明為 final 的,不可被繼承。 String 類實現了 Serializable 介面:表示字元串是支持序列化的。實現了 Comparable 介面: ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...