人生苦短我用Python

Programs must be written for people to read, and only incidentally for machines to execute.

要寫出 Pythonic(優(yōu)雅的、地道的、整潔的)代碼,還要平時(shí)多觀察那些大牛代碼,Github 上有很多非常優(yōu)秀的源代碼值得閱讀,比如:requests、flask、tornado,筆者列舉一些常見的 Pythonic 寫法,希望能給你帶來一點(diǎn)啟迪。

1、變量交換

大部分編程語言中交換兩個(gè)變量的值時(shí),不得不引入一個(gè)臨時(shí)變量:

 >>> a = 1
 >>> b = 2
 >>> tmp = a
 >>> a = b
 >>> b = tmp

pythonic
>>> a, b = b, a

2、循環(huán)遍歷區(qū)間元素

for i in [0, 1, 2, 3, 4, 5]: print i2 或者 for i in range(6): print i2
pythonic
for i in xrange(6): print i2
xrange 返回的是生成器對象,生成器比列表更加節(jié)省內(nèi)存,不過需要注意的是 xrange 是 python2 中的寫法,python3 只有 range 方法,特點(diǎn)和 xrange 是一樣的。

3、帶有索引位置的集合遍歷

遍歷集合時(shí)如果需要使用到集合的索引位置時(shí),直接對集合迭代是沒有索引信息的,普通的方式使用:

colors = ['red', 'green', 'blue', 'yellow'] for i in range(len(colors)): print i, '--->', colors[i]

pythonic

for i, color in enumerate(colors): print i, '--->', color
4、字符串連接

字符串連接時(shí),普通的方式可以用 + 操作

names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie'] s = names[0] for name in names[1:]: s += ', ' + name print s

pythonic

print ', '.join(names)
join 是一種更加高效的字符串連接方式,使用 + 操作時(shí),每執(zhí)行一次+操作就會(huì)導(dǎo)致在內(nèi)存中生成一個(gè)新的字符串對象,遍歷8次有8個(gè)字符串生成,造成無謂的內(nèi)存浪費(fèi)。而用 join 方法整個(gè)過程只會(huì)產(chǎn)生一個(gè)字符串對象。

5、打開/關(guān)閉文件

執(zhí)行文件操作時(shí),最后一定不能忘記的操作是關(guān)閉文件,即使報(bào)錯(cuò)了也要 close。普通的方式是在 finnally 塊中顯示的調(diào)用 close 方法。

f = open('data.txt') try: data = f.read() finally: f.close()

pythonic

with open('data.txt') as f: data = f.read()
使用 with 語句,系統(tǒng)會(huì)在執(zhí)行完文件操作后自動(dòng)關(guān)閉文件對象。

6、列表推導(dǎo)式

能夠用一行代碼簡明扼要地解決問題時(shí),絕不要用兩行,比如

result = [] for i in range(10): s = i 2 result.append(s)
pythonic

[i2 for i in xrange(10)]
與之類似的還有生成器表達(dá)式、字典推導(dǎo)式,都是很 pythonic 的寫法。

7、善用裝飾器

裝飾器可以把與業(yè)務(wù)邏輯無關(guān)的代碼抽離出來,讓代碼保持干凈清爽,而且裝飾器還能被多個(gè)地方重復(fù)利用。比如一個(gè)爬蟲網(wǎng)頁的函數(shù),如果該 URL 曾經(jīng)被爬過就直接從緩存中獲取,否則爬下來之后加入到緩存,防止后續(xù)重復(fù)爬取。

def web_lookup(url, saved={}): if url in saved: return saved[url] page = urllib.urlopen(url).read() saved[url] = page return page
pythonic

import urllib #py2 import urllib.request as urllib # py3 def cache(func): saved = {} def wrapper(url): if url in saved: return saved[url] else: page = func(url) saved[url] = page return page return wrapper @cache def web_lookup(url): return urllib.urlopen(url).read()
用裝飾器寫代碼表面上感覺代碼量更多,但是它把緩存相關(guān)的邏輯抽離出來了,可以給更多的函數(shù)調(diào)用,這樣總的代碼量就會(huì)少很多,而且業(yè)務(wù)方法看起來簡潔了。

8、合理使用列表

列表對象(list)是一個(gè)查詢效率高于更新操作的數(shù)據(jù)結(jié)構(gòu),比如刪除一個(gè)元素和插入一個(gè)元素時(shí)執(zhí)行效率就非常低,因?yàn)檫€要對剩下的元素進(jìn)行移動(dòng)

names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie'] names.pop(0) names.insert(0, 'mark')
pythonic

from collections import deque names = deque(['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']) names.popleft() names.appendleft('mark')
deque 是一個(gè)雙向隊(duì)列的數(shù)據(jù)結(jié)構(gòu),刪除元素和插入元素會(huì)很快

9、序列解包

p = 'vttalk', 'female', 30, 'python@qq.com' name = p[0] gender = p[1] age = p[2] email = p[3]
pythonic

name, gender, age, email = p
10、遍歷字典的 key 和 value

方法一速度沒那么快,因?yàn)槊看蔚臅r(shí)候還要重新進(jìn)行hash查找 key 對應(yīng)的 value。

方法二遇到字典非常大的時(shí)候,會(huì)導(dǎo)致內(nèi)存的消耗增加一倍以上

  # 方法一

for k in d:
print k, '--->', d[k]
# 方法二
for k, v in d.items():
print k, '--->', v``

pythonic

for k, v in d.iteritems(): print k, '--->', v
iteritems 返回迭代器對象,可節(jié)省更多的內(nèi)存,不過在 python3 中沒有該方法了,只有 items 方法,等值于 iteritems。

歡迎加入我的Python交流群
626062078
覺得不錯(cuò)就贊一個(gè)吧 (o)/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容