何為Pythonic
在《The Zen of Python》中性昭,有以下說(shuō)明Python的禪意的內(nèi)容:
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
文中的句子一直在指引我們寫(xiě)出更美的Python代碼岩馍,更加Pythonic的代碼。Pythonic在這里可以理解成更加符合Python風(fēng)格的優(yōu)雅的代碼蚕捉,Python中提供了非常多的語(yǔ)法糖,合理使用的話(huà)我們可以讓整個(gè)代碼可讀性更強(qiáng),性能更好啃匿,維護(hù)成本更低,這樣也就達(dá)到了我們所謂的Pythonic。
如何做到Pythonic
寫(xiě)出Pythonic的代碼需要我們?cè)诹私釶ython的語(yǔ)法特性的基礎(chǔ)上也了解其底層的實(shí)現(xiàn)溯乒,否則一個(gè)看似美麗的代碼可能存在非常大的性能危機(jī)夹厌,例如列表操作,若每次進(jìn)行查詢(xún)的時(shí)候都新建一份數(shù)據(jù)裆悄,將會(huì)是一個(gè)惡夢(mèng)矛纹。
最近瀏覽Youtube的時(shí)候看到了這樣的一個(gè)視頻,其中講述了關(guān)于如何寫(xiě)出Pythonic代碼的技巧光稼。
1.字典查找優(yōu)化
通過(guò)使用字典或南,我們的查詢(xún)時(shí)間可以縮小到O(1),因?yàn)樽值涞讓佑玫?strong>Hash艾君,但這是個(gè)以空間換時(shí)間的做法采够,需要視情況而定。
2.使用slots進(jìn)行內(nèi)存優(yōu)化
__slots__
可以用來(lái)限制class能添加的屬性冰垄,他主要是告訴Python不要使用字典蹬癌,而使用一個(gè)固定量的內(nèi)存來(lái)保存所有的屬性,這樣能達(dá)到減輕內(nèi)存負(fù)擔(dān)的目的虹茶,通過(guò)使用這種方法逝薪,內(nèi)存可以減少30%~50%的占用。具體可以看以下這篇文章蝴罪。
參考:
3.合并字典
圖中這種方式是不Pythonic的董济,可讀性并不是特別好,以下提供了一種更經(jīng)典的Pythonic的處理方式要门。他通過(guò)字典的update
方法來(lái)更新字典內(nèi)容虏肾。
另一種方式是通過(guò)字典表達(dá)式:
4.使用yield
通過(guò)yield
我們可以得到內(nèi)存友好的生成器,在需要的時(shí)候才返回我們需要的值暂衡,而不是一次性生成在內(nèi)存中询微,是一種lazy
的做法。
具體可以看此文中的生成器
:Python難點(diǎn)解析---初級(jí)篇3.迭代(可迭代狂巢、迭代器撑毛、生成器)
5.Lambda表達(dá)式
使用Lambda表達(dá)式我們可以來(lái)創(chuàng)建匿名函數(shù),對(duì)于一些簡(jiǎn)單的函數(shù)唧领,我們不是很必要使用def
關(guān)鍵字來(lái)定義函數(shù)藻雌,通過(guò)Lambda表達(dá)式我們可以很簡(jiǎn)潔的得到函數(shù),例如我們有一個(gè)得到奇數(shù)的函數(shù)斩个,我們可以這樣定義:
oddfunc = lambda x : x % 2 == 0
#可以用于過(guò)濾列表之類(lèi)的~
6.給自定義類(lèi)型添加迭代
可以通過(guò)實(shí)現(xiàn)__iter__
方法來(lái)實(shí)現(xiàn)迭代胯杭,實(shí)例如下:
class ShoppingCart:
def __init__(self):
self.items = []
def add_item(self, it):
self.items.append(it)
# def __iter__(self):
# return self.items.__iter__()
def __iter__(self):
for i in sorted(self.items, key=lambda x: -x.price):
yield i
class CartItem:
def __init__(self, name, price):
self.price = price
self.name = name
具體可參考這個(gè)文章:Python難點(diǎn)解析---初級(jí)篇3.迭代(可迭代、迭代器受啥、生成器)
7.使用列表解析式
列表解析式是Python提供的用于生成列表的語(yǔ)法糖做个,通過(guò)添加限制條件和循環(huán)我們可以得到符合我們條件的列表數(shù)據(jù)鸽心。
例如我們要得到一組超過(guò)10的列表數(shù)據(jù):
list_comperhension = [x for x in range(20) if x > 10]
print(list_comperhension)
通過(guò)簡(jiǎn)潔的語(yǔ)法即可得到符合條件的列表,是一種非常Pythonic的方式居暖。
8.列表切片操作
關(guān)于列表的切片操作顽频,基本的規(guī)則可以這樣表示:list[start:end::step]
- start表示開(kāi)始
- end表示結(jié)束的索引
- step表示索引的步長(zhǎng)
最重要的一點(diǎn)是,索引值是>=start而<end
的太闺,例如list[1:3]糯景,則返回列表的索引值為1 2
。
參考: