一文看懂Python的控制结构:for、while、if…都有了
導讀:本文介紹Python中的常見控制結構。
作者:挪亞·吉夫特(Noah Gift)
來源:大數據DT(ID:hzdashuju)
傳統Python語言的主要控制結構是for循環。然而,需要注意的是for循環在Pandas中不常用,因此Python中for循環的有效執行并不適用于Pandas模式。一些常見控制結構如下。
for循環
while循環
if/else語句
try/except語句
生成器表達式
列表推導式
模式匹配
所有的程序最終都需要一種控制執行流的方式。本節介紹一些控制執行流的技術。
01 for循環
for循環是Python的一種最基本的控制結構。使用for循環的一種常見模式是使用range函數生成數值范圍,然后對其進行迭代。
res?=?range(3) print(list(res))#輸出:[0, 1, 2] for?i?in?range(3): print(i)'''輸出: 0 1 2 '''for循環列表
使用for循環的另一種常見模式是對列表進行迭代。
martial_arts?=?["Sambo","Muay?Thai","BJJ"] for?martial_art?in?martial_arts:print(f"{?martial_art}?has?influenced\modern?mixed?martial?arts")'''輸出: Sambo?has?influenced?modern?mixed?martial?arts Muay?Thai?has?influenced?modern?mixed?martial?arts BJJ?has?influenced?modern?mixed?martial?arts '''02 while循環
while循環是一種條件有效就會重復執行的循環方式。while循環的常見用途是創建無限循環。在本示例中,while循環用于過濾函數,該函數返回兩種攻擊類型中的一種。
def?attacks():list_of_attacks?=?["lower_body",?"lower_body","upper_body"]print("There?are?a?total?of?{lenlist_of_attacks)}\attacks?coming!")for?attack?in?list_of_?attacks:yield?attack attack?=?attacks() count?=?0 while?next(attack)?==?"lower_body":count?+=1print(f"crossing?legs?to?prevent?attack?#{count}") else:count?+=?1print(f"This?is?not?lower?body?attack,?\ I?will?cross?my?arms?for#?count}")'''輸出: There?are?a?total?of?3?attacks?coming! crossing?legs?to?prevent?attack?#1 crossing?legs?to?prevent?attack?#2 This?is?not?a?lower?body?attack,?I?will?cross?my?arms?for?#3 '''03 if/else語句
if/else語句是一條在判斷之間進行分支的常見語句。在本示例中,if/elif用于匹配分支。如果沒有匹配項,則執行最后一條else語句。
def?recommended_attack(position):"""Recommends?an?attack?based?on?the?position"""if?position?==?"full_guard":print(f"Try?an?armbar?attack")elif?position?==?"half_guard":print(f"Try?a?kimura?attack")elif?position?==?"fu1l_mount":print(f"Try?an?arm?triangle")else:print(f"You're?on?your?own,?\there?is?no?suggestion?for?an?attack") recommended_attack("full_guard")#輸出:Try an armbar attackrecommended_attack("z_guard")#輸出:You're on your own, there is no suggestion for an attack04 生成器表達式
生成器表達式建立在yield語句的概念上,它允許對序列進行惰性求值。生成器表達式的益處是,在實際求值計算前不會對任何內容進行求值或將其放入內存。這就是下面的示例可以在生成的無限隨機攻擊序列中執行的原因。
在生成器管道中,諸如 “arm_triangle”的小寫攻擊被轉換為“ARM_TRIANGLE”,接下來刪除其中的下劃線,得到“ARM TRIANGLE”。
?def?lazy_return_random_attacks():"""Yield?attacks?each?time"""import?randomattacks?=?{"kimura":?"upper_body","straight_ankle_lock":?"lower_body","arm_triangle":?"upper_body","keylock":?"upper_body","knee_bar":?"lower_body"}while?True:random_attack?random.choices(list(attacks.keys()))yield?random?attack#Make?all?attacks?appear?as?Upper?Case upper_case_attacks?=?\(attack.pop().upper()?for?attack?in?\lazy_return_random_attacks()) next(upper-case_attacks)#輸出:ARM-TRIANGLE##?Generator?Pipeline:?One?expression?chains?into?the?next #Make?all?attacks?appear?as?Upper?Case upper-case_attacks?=\(attack.?pop().upper()?for?attack?in\lazy_return_random_attacks()) #remove?the?underscore remove?underscore?=\(attack.split("_")for?attack?in\upper-case_attacks) #create?a?new?phrase new_attack_phrase?=\("?".join(phrase)?for?phrase?in\remove_underscore) next(new_attack_phrase)#輸出:'STRAIGHT ANKLE LOCK' for?number?in?range(10):print(next(new_attack_phrase))'''輸出: KIMURA KEYLOCK STRAIGHT?ANKLE?LOCK '''05 列表推導式
語法上列表推導式與生成器表達式類似,然而直接對比它們,會發現列表推導式是在內存中求值。此外,列表推導式是優化的C代碼,可以認為這是對傳統for循環的重大改進。
martial_arts?=?["Sambo",?"Muay?Thai",?"BJJ"] new_phrases?[f"mixed?Martial?Arts?is?influenced?by?\(martial_art)"?for?martial_art?in?martial_arts] print(new_phrases) ['Mixed?Martial?Arts?is?influenced?by?Sambo',?\ 'Mixed?Martial?Arts?is?influenced?by?Muay?Thai',?\ 'Mixed?Martial?Arts?is?influenced?by?BJJ']06 中級主題
有了這些基礎知識后,重要的是不僅要了解如何創建代碼,還要了解如何創建可維護的代碼。創建可維護代碼的一種方法是創建一個庫,另一種方法是使用已經安裝的第三方庫編寫的代碼。其總體思想是最小化和分解復雜性。
使用Python編寫庫
使用Python編寫庫非常重要,之后將該庫導入項目無須很長時間。下面這些示例是編寫庫的基礎知識:在存儲庫中有一個名為funclib的文件夾,其中有一個_init_ .py文件。要創建庫,在該目錄中需要有一個包含函數的模塊。
首先創建一個文件。
touch?funclib/funcmod.py然后在該文件中創建一個函數。
"""This?is?a?simple?module""" def?list_of_belts_in_bjj():"""Returns?a?list?of?the?belts?in?Brazilian?jiu-jitsu"""belts=?["white",?"blue",?"purple",?"brown",?"black"]return?belts import?sys;sys.path.append("..") from?funclib?import?funcmod funcmod.list_of_belts_in-bjj()#輸出:['white', 'blue', 'purple', 'brown', 'black']導入庫
如果庫是上面的目錄,則可以用Jupyter添加sys.path.append方法來將庫導入。接下來,使用前面創建的文件夾/文件名/函數名的命名空間導入模塊。
安裝第三方庫
可使用pip install命令安裝第三方庫。請注意,conda命令(https://conda.io/docs/user-guide/tasks/manage-pkgs.html)是pip命令的可選替代命令。如果使用conda命令,那么pip命令也會工作得很好,因為pip是virtualenv虛擬環境的替代品,但它也能直接安裝軟件包。
安裝pandas包。
pip?install?pandas另外,還可使用requirements.txt文件安裝包。
>?ca?requirements.txt pylint pytest pytest-cov click jupyter nbval>?pip?install?-r?requirements.txt下面是在Jupyter Notebook中使用小型庫的示例。值得指出的是,在Jupyter Notebook中創建程序代碼組成的巨型蜘蛛網很容易,而且非常簡單的解決方法就是創建一些庫,然后測試并導入這些庫。
"""This?is?a?simple?module"""import?pandas?as?pddef?list_of_belts_in_bjj():"""Returns?a?list?of?the?belts?in?Brazilian?jiu-jitsu"""belts?=?["white",?"blue",?"purple",?"brown",?"black"]return?beltsdef?count_belts():"""Uses?Pandas?to?count?number?of?belts"""belts?=?list_of_belts_in_bjj()df?=?pd.Dataframe(belts)res?=?df.count()count?=?res.values.tolist()[0]return?count from?funclib.funcmod?import?count_belts print(count_belts())#輸出:5類
可在Jupyter Notebook中重復使用類并與類進行交互。最簡單的類類型就是一個名稱,類的定義形式如下。
class?Competitor:?pass該類可實例化為多個對象。
class?Competitor:?pass conor?=?Competitor() conor.name?=?"Conor?McGregor" conor.age?=?29 conor.weight?=?155 nate?=?Competitor() nate.name?=?"Nate?Diaz" nate.age?=?30 nate.weight?=?170 def?print_competitor?_age(object):"""Print?out?age?statistics?about?a?competitor"""print(f"{object.name}?is?{object.age}?years?old") print_competitor_age(nate)#輸出:Nate Diaz is 30 years old print_competitor_age(conor)#輸出:Conor McGregor is 29 years old類和函數的區別
類和函數的主要區別包括:
函數更容易解釋。
函數(典型情況下)只在函數內部具有狀態,而類在函數外部保持不變的狀態。
類能以復雜性為代價提供更高級別的抽象。
關于作者:挪亞·吉夫特(Noah Gift),加州大學戴維斯分校工商管理研究生院機器學習課程講師,是AWS認證的架構師,也是AWS云端機器學習專家,長期為包括初創公司在內的企業提供機器學習、云架構和CTO級別的咨詢服務。
本文摘編自《人工智能開發實踐:云端機器學習導論》,經出版方授權發布。
?往期推薦?
????
19 個接私活平臺匯總升級版,你有技術就有錢
肝!一行 Python 代碼實現并行
Python+統計學 | 探索常用的數據分析統計分布
B站大佬開發的這款無障礙看片神器火了,我有一個大膽的想法...
總結
以上是生活随笔為你收集整理的一文看懂Python的控制结构:for、while、if…都有了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一顿骚操作!我将 SQL 耗时从 302
- 下一篇: 微软太良心,这么强大的软件竟然完全免费!