如何優雅的寫好Pythonic代碼?
Python 與其它語言(比如Java或者C++)相比有比較大的區別,其中最大的特點就是非常簡潔。如果按照其它語言的思路來寫Python代碼,則會使得代碼繁瑣複雜,並且容易出現Bug。在Python語言中,有個詞很火,Pythonic。有的同學可能不明白這個詞的意義,小編的理解就是用Python的寫法寫代碼,而非是其它語言的通用的寫法,寫出Python的特點,寫出Python的風格。
下面,就通過幾個示例來看一下不同思維的Python代碼的差異。
1、變數值交換
這個問題最常見,大家從最開始寫Java及C++等語言代碼都會遇到這個問題。通常是通過一個臨時變數來實現的:
tmp = a
a = b
b = tmp
而Python中可以直接交換兩個變數,即:
a, b = b, a
2、列表推導式
列表推導式是Java及C++等語言沒有的特性,能夠很簡潔的實現for循環,可以應用於列表,集合或者字典。
例如我們要求20以內的整除3的數的平方的列表,可以用如下代碼實現:
numbers = []
forxinxrange(20):
ifx %3==:
numbers.append(x*x)
而通過列表推導式一行代碼即可實現:
numbers = [x*xforxinrange(20)ifx %3==]
列表推導式也可以用於集合和字典,將[...]變為{...}即可。集合和字典的實現如下所示:
numbers =
numbers =
3、字元串拼接
這是一個老生常談的問題,當我們需要將數個字元串拼接的時候,習慣性的使用 "+" 作為連接字元串的手段。
然而,由於像字元串這種不可變對象在內存中生成後無法修改,合併後的字元串會重新開闢出一塊內存空間來存儲。因此每合併一次就會單獨開闢一塊內存空間,這樣會佔用大量的內存空間,嚴重影響代碼的效率。
words = [ I , , love , , Python , . ]
sentence =
forwordinwords:
sentence += + word
解決這個問題的辦法是使用字元串連接的join,Python寫法如下:
words = [ I , , love , , Python , . ]
sentence = .join(words)
4、如何快速翻轉字元串
Java或者C++等語言的寫法是新建一個字元串,從最後開始訪問原字元串:
a = I love Python.
reverse_a =
foriinrange(, len(a)):
reverse_a += a[len(a) - i -1]
而Python則將字元串看作list,而列表可以通過切片操作來實現反轉:
a = I love Python.
reverse_a = a[::-1]
5、for/else語句
在C語言或Java語言中,我們尋找一個字元是否在一個list中,通常會設置一個布爾型變數表示是否找到:
cities = [ BeiJing , TianJin , JiNan , ShenZhen , WuHan ]
tofind = Shanghai
found =False
forcityincities:
iftofind == city:
print Found!
found =True
break
ifnotfound:
print Not found!
而Python中的通過for...else...會使得代碼很簡潔,注意else中的代碼塊僅僅是在for循環中沒有執行break語句的時候執行:
cities = [ BeiJing , TianJin , JiNan , ShenZhen , WuHan ]
tofind = Shanghai
forcityincities:
iftofind == city:
print Found!
break
else:
# 執行else中的語句意味著沒有執行break
print Not found!
另外,while以及try關鍵字都可以和else搭配使用,具體可以參考小編之前寫的文章Python中else塊那點事。
6、迭代對象善用enumerate類
enumerate類接收兩個參數,其中一個是可以迭代的對象,另外一個是開始的索引。比如,我們想要列印一個列表的索引及其內容,可以用如下代碼實現:
cities = [ BeiJing , TianJin , JiNan , ShenZhen , WuHan ]
index =
forcityincities:
index = index +1
printindex, : , city
而通過使用enumerate則極大簡化了代碼,這裡索引設置為從1開始(默認是從0開始):
cities = [ BeiJing , TianJin , JiNan , ShenZhen , WuHan ]
forindex, cityinenumerate(cities,1):
printindex,":", city
7、通過lambda來定義函數
lambda可以返回一個可以調用的函數對象,會使得代碼更為簡潔。若不使用lambda則需要單獨定義一個函數:
deff(x):
returnx * x
map(f, [1,2,3,4,5,6,7,8,9])
使用lambda後僅僅需要一行代碼:
map(lambdax: x * x, [1,2,3,4,5,6,7,8,9])
這裡注意,lambda生成的是一個可以像其他函數一樣使用的函數對象,即
deff(x):
returnx * x
等價於
lambdax: x * x
8、應用上下文管理
在打開文件時,通常是通過捕獲異常來進行實現的,並且在finally模塊中對文件來進行關閉:
try:
file = open( python.txt )
forlineinfile:
printline
except:
print"File error!"
finally:
file.close()
而通過上下文管理中的with語句可以讓代碼非常簡潔:
withopen( python.txt )asfile:
forlineinfile:
printline
具體原理可以參考小編之前寫的with語句那點事。
9、使用裝飾器
裝飾器在Python中應用特別廣泛,其特點是可以在具體函數執行之前或者之後做相關的操作,比如:執行前列印執行函數的相關信息,對函數的參數進行校驗;執行後記錄函數調用的相關流水日誌等。使用裝飾器最大的好處是使得函數功能單一化,僅僅處理業務邏輯,而不附帶其它功能。
在函數調用前列印時間函數名相關的信息,不使用裝飾器可以用如下代碼實現:
fromtimeimportctime
deffoo():
print( [%s] %s() is called % (ctime(), foo.__name__))
print( Hello, Python )
這樣寫的問題是業務邏輯中會夾雜參數檢查,日誌記錄等信息,使得代碼邏輯不夠清晰。所以,這種場景需要使用裝飾器:
fromtimeimportctime
defdeco(func):
defdecorator(*args, **kwargs):
print( [%s] %s() is called % (ctime(), func.__name__))
returnfunc(*args, **kwargs)
returndecorator
@deco
deffoo():
print( Hello, Python )
如果想深入理解裝飾器,可以閱讀小編之前寫的深入理解Python中的裝飾器。
10、使用生成器
生成器與列表最大的區別就是,列表是一次性生成的,需要較大的內存空間;而生成器是需要的時候生成的,基本不佔用內存空間。生成器分為生成器表達式和生成器函數。
先看一下列表:
l = [xforxinrange(10)]
改為生成器只需要將[...]變為(...),即
g = (xforxinrange(10))
至於生成器函數,是通過yield關鍵字來實現的,我們以計算斐波那契數列為例,使用列表可以用如下代碼來實現:
deffib(max):
n, a, b =,,1
fibonacci = []
whilen < max:
fibonacci.append(b)
a, b = b, a + b
n = n +1
returnfibonacci
而使用生成器則變為:
deffib(max):
n, a, b =,,1
whilen < max:
yieldb
a, b = b, a + b
n = n +1
對生成器感興趣的可以深入閱讀小編之前寫的文章生成器那點事及深入理解生成器及協程。
這些Pythonic的代碼是否讓你耳目一新?你還能寫出哪些Pythonic的代碼?
看完本文有收穫?請轉發分享給更多人
關注「Python那些事」,提升Python技能
※R&Python圖譜及速查表
※運維不會Python升職加薪基本與你無緣!
※「老兵愛學習」之《顛覆你的Python介面自動化測試》
※Python躍升編程語言第一名!
※Packt 年度技能調查:Python 最火 IDE 最受歡迎
TAG:Python |
※就像一隻優雅的精靈:Varenna Poliform
※Chanel該如何穿更優雅?
※如何成為 風情萬種 優雅拉丁女郎?穿她就對了Johanna Ortiz
※是的,我們又被Amal Clooney的優雅驚艷了!
※是air jordan還是adidas?是優雅還是狂野?
※超凡脫俗的優雅 Beyond elegance
※紀念Hubert de Givenchy:節制的優雅
※夏季優雅生活秘方 How to stay elegant in summer?
※如何優雅地說「wo cao」?
※如何優雅地說「wo cao 」?
※Louis Vuitton時裝走秀款,優雅摩登又現代!
※法式新時髦的代表Jeanne Damas,隨性而優雅!
※Henri Matisse/優雅的「野獸」
※問侯||夏季優雅生活秘方 How to stay elegant in summer?
※Clarks Second Skin系列:靈動優雅 譜寫經典
※Hubert de Givenchy——優雅的設計師,永恆的學徒
※Zynni Cashmere 優雅就是拈住時光的羊絨衣角
※以黑色詮釋簡約優雅:Longines浪琴錶Legend Diver復刻潛水腕錶
※優雅的舞蹈 堅持瑜伽 你也可以做到 插畫師 Cynthia Tedy
※穿Simone Rocha的優雅 「老少女」