關(guān)于Pythonic定義,參考文章:What does pythonic mean?
以下通過對(duì)比Bad way和Elegant way介紹一些常見的Pythonic寫法。
使用字典默認(rèn)值
需求:在取dict的值的時(shí)候,假設(shè)某個(gè)key不存在,希望賦予其一個(gè)默認(rèn)的值。
比較糟糕的方式:使用if去判斷key是否存在,不存在則給其賦予默認(rèn)值。如下:
person = {
"name": "xiaohong",
"age": 12,
}
name = person['name'] if person.get('name') else "nobody"
優(yōu)雅的寫法:
name = person.get("name", "nobody")
dict類型的get方法是可以設(shè)置缺省值的。
使用enumerate關(guān)鍵字
需求:對(duì)列表進(jìn)行迭代的時(shí)候,需要同時(shí)訪問偏移量。
比較糟糕的方式:定義一個(gè)起始索引值,每迭代一次索引值計(jì)數(shù)一次。如下:
names = ["Zhang san", "Li si", "Wang wu"]
index = 0
for name in names:
print("The {0} is in position: {1}".format(name, index))
index += 1
或者
names = ["Zhang san", "Li si", "Wang wu"]
for position in range(0, len(names)):
print("The {0} is in position: {1}".format(names[position], position))
優(yōu)雅的寫法:
names = ["Zhang san", "Li si", "Wang wu"]
for position, name in enumerate(names):
print("The {0} is in position: {1}".format(name, position))
用enumerate關(guān)鍵字進(jìn)行迭代的過程中可同時(shí)返回索引以及值。
for else的巧用
需求:在一個(gè)列表中查找某個(gè)元素,如果,找到這個(gè)元素,立刻結(jié)束查找;如果未查找到則打印未找到。
比較糟糕的方式:定義一個(gè)變量用來標(biāo)示是否找到。如下:
names = ["Zhang san", "Li si", "Wang wu"]
for name in names:
if name == 'Gou er dan':
found = True
break
if found is False:
print("未找到")
優(yōu)雅的寫法:
names = ["Zhang san", "Li si", "Wang wu"]
found = False
for name in names:
if name == 'Gou er dan':
found = True
break
else:
print("未找到")
for else語句,如果for循環(huán)執(zhí)行完畢,則會(huì)執(zhí)行else語句塊,否則,不執(zhí)行else語句塊。
with關(guān)鍵字的使用
需求:讀寫文件或者使用進(jìn)程鎖。
比較糟糕的方式,手動(dòng)管理文件的關(guān)閉或者打開。如:
f = open("test.txt", "r")
try:
text = f.read()
print(text)
finally:
f.close()
或者
import threading
lock = threading.Lock()
lock.acquire()
try:
print("Balabala")
finally:
lock.release()
優(yōu)雅的寫法:
with open("test.txt", "r") as f:
print(f.read())
和
import threading
lock = threading.Lock()
with lock:
print("balabala")
使用with避免自己手動(dòng)釋放資源。
同時(shí)遍歷二個(gè)列表
需求:同時(shí)遍歷二個(gè)列表。
比較糟糕的方式,定義下標(biāo)去索引,如:
numbers = [1, 2, 3, 4]
english = ['one', 'two', 'three']
n = min(len(numbers), len(english))
for i in range(n):
print("{0} is {1}".format(numbers[i], english[i]))
優(yōu)雅的寫法:
numbers = [1, 2, 3, 4]
english = ['one', 'two', 'three']
for number, name in zip(numbers, english):
print("{0} is {1}".format(number, name))
使用takewhile代替break
需求:在每次循環(huán)開始時(shí),判斷循環(huán)是否需要提前結(jié)束。
不地道的寫法:使用break。如:
for user in users:
if not is_qualified(user):
break
地道的寫法:
from itertools import takewhile
for user in takewhile(is_qualified, users):
# ....
對(duì)于這類需要提前中斷的循環(huán),我們可以使用 takewhile() 函數(shù)來簡(jiǎn)化它。takewhile(predicate,iterable)會(huì)在迭代iterable的過程中不斷使用當(dāng)前對(duì)象作為參數(shù)調(diào)用predicate函數(shù)并測(cè)試返回結(jié)果,如果函數(shù)返回值為真,則生成當(dāng)前對(duì)象,循環(huán)繼續(xù)。否則立即中斷當(dāng)前循環(huán)。
使用defaultdict
需求:統(tǒng)計(jì)一組字符串出現(xiàn)的頻率。
不優(yōu)雅的寫法:
names = ["Zhang san", "Li si", "Li si", "Wang wu", "Zhang san", "Wang wu"]
name_count = dict()
for name in names:
if not name_count.get(name):
name_count['name'] = 0
else:
name_count['name'] += 1
優(yōu)雅的寫法:
from collections import defaultdict
names = ["Zhang san", "Li si", "Li si", "Wang wu", "Zhang san", "Wang wu"]
name_count = defaultdict(int)
for name in names:
name_count[name] += 1
更加優(yōu)雅的寫法:
from collections import Counter
names = ["Zhang san", "Li si", "Li si", "Wang wu", "Zhang san", "Wang wu"]
print(Counter(names))
還有很多,下次接著寫...
并且,繼續(xù)更新中 ...