五個(gè)實(shí)用的Python編程小技巧
簡(jiǎn)介
Python是一門很棒的編程語(yǔ)言,具有簡(jiǎn)潔和抽象為特點(diǎn)。Python編程涉及許多技巧,能用盡量少的代碼、更易理解的代碼編寫程序。本文介紹五個(gè)實(shí)用的Python編程技巧。
1. 列表生成式
通過(guò)使用列表生成式,可以用一行簡(jiǎn)潔的代碼生成列表、字典、集合,不需要編寫多行代碼。
列表生成式最常用于列表,但其結(jié)構(gòu)與其他數(shù)據(jù)結(jié)構(gòu)是相同的。
例如,下面這段代碼是用于獲取數(shù)字的平方:
output = []
for i in range(10):
output.append(i**2)
print(output)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
可以使用列表生成式縮短代碼:
output = [i**2 for i in range(10)]
print(output)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
列表生成式的語(yǔ)法非常簡(jiǎn)單,可以通過(guò)以下方式解釋:
使用兩個(gè)方括號(hào)表示列表[在此放置邏輯]。方括號(hào)內(nèi)的部分與常規(guī)的for循環(huán)幾乎相同。
右側(cè)是常規(guī)“for循環(huán)”的語(yǔ)法。在左側(cè),可以訪問(wèn)“for循環(huán)”的元素,并在那里進(jìn)行計(jì)算。
# [<Left hand side: calculations of i> for i in range(10)]
CompressedList = [i+2*i for i in range(10)]
列表生成式也適用于字典、集合和生成器,可點(diǎn)擊如下鏈接查看示例。
【字典、集合和生成器】:https://book.pythontips.com/en/latest/comprehensions.html
2. Lambda函數(shù)
Lambda函數(shù)是Python中的單行代碼函數(shù)。它們的功能與普通函數(shù)相同,但更簡(jiǎn)短、更易于使用。然而,與普通函數(shù)不同的是,它們是匿名的。這意味著該函數(shù)沒(méi)有與之關(guān)聯(lián)的標(biāo)識(shí)符。
這意味著如果不將lambda函數(shù)存儲(chǔ)到變量中,就永遠(yuǎn)無(wú)法再次訪問(wèn)它。這非常適合一次性使用。
例如,下面的這段代碼是根據(jù)第二個(gè)元素而不是第一個(gè)元素,對(duì)包含2個(gè)元素組成的元組列表進(jìn)行排序:
l = [(1, 2), (8, 0), (2, 1)]
def secondElement(x):
return x[1]
l.sort(key=secondElement)
print(l)
# [(8, 0), (2, 1), (1, 2)]
可以使用匿名函數(shù),將代碼縮短為如下格式:
l = [(1, 2), (8, 0), (2, 1)]
l.sort(key=lambda x : x[1])
print(l)
# [(8, 0), (2, 1), (1, 2)]
用戶很可能永遠(yuǎn)都不需要再次使用函數(shù)secondElement,這就是lambda函數(shù)為什么如此強(qiáng)大的一個(gè)很好的例子。
Lambda函數(shù)的語(yǔ)法很簡(jiǎn)單。在左側(cè)使用lambda,然后在空格后寫出所有需要的參數(shù),參數(shù)之間用逗號(hào)分隔。之后,使用:分隔參數(shù)和計(jì)算值。計(jì)算得到的值從lambda函數(shù)中返回。以下是另一個(gè)示例:
# lambdaFunction = lambda <arguments here> : <operation here>
add = lambda x,y : x+y
print(add(2,3))
# 5
3. 集合collections
集合是Python中的內(nèi)置數(shù)據(jù)結(jié)構(gòu)模塊。與Python的默認(rèn)數(shù)據(jù)類型相比,這些集合提供了更多的可擴(kuò)展性和便利性。創(chuàng)建的類型有很多種,下面列出了最重要的幾種。
# 如何導(dǎo)入collections
from collections import defaultdict
from collections import OrderedDict
from collections import Counter
from collections import deque
from collections import namedtuple
3.1 默認(rèn)字典(Default Dictionary)
當(dāng)不存在鍵時(shí),會(huì)返回一個(gè)默認(rèn)值而不是引發(fā)KeyError的字典??梢酝ㄟ^(guò)將函數(shù)或常量值傳遞給defaultdict構(gòu)造函數(shù)來(lái)創(chuàng)建它。
3.2 有序字典(Ordered Dictionary)
可記錄其項(xiàng)的插入順序并允許基于該順序進(jìn)行迭代、刪除和重新排序的字典。可以通過(guò)將鍵值對(duì)的可迭代對(duì)象或關(guān)鍵字參數(shù)傳遞給OrderedDict構(gòu)造函數(shù)來(lái)創(chuàng)建它。
3.3 計(jì)數(shù)器(Counter)
用于計(jì)算序列或可迭代對(duì)象中每個(gè)元素出現(xiàn)次數(shù)的字典??梢酝ㄟ^(guò)將可迭代對(duì)象、映射或關(guān)鍵字參數(shù)傳遞給Counter構(gòu)造函數(shù)來(lái)創(chuàng)建它。它具有對(duì)計(jì)數(shù)器執(zhí)行常見(jiàn)操作的方法,如加法、減法、交集、并集等。
3.4 雙端隊(duì)列(Deque)
支持在兩端添加和刪除元素,時(shí)間復(fù)雜度為O(1)的雙端隊(duì)列。可以通過(guò)將可迭代對(duì)象傳遞給deque構(gòu)造函數(shù)來(lái)創(chuàng)建它。它具有用于旋轉(zhuǎn)、擴(kuò)展和一次彈出多個(gè)元素的方法。
3.5 具名元組(Named Tuples)
每個(gè)元素都有名稱,并且可以通過(guò)點(diǎn)符號(hào)或索引進(jìn)行訪問(wèn)的元組。可以通過(guò)使用namedtuple函數(shù)定義一個(gè)命名元組類,并將類名和字段名作為參數(shù)來(lái)創(chuàng)建它。它具有用于創(chuàng)建、替換、轉(zhuǎn)換和操作命名元組的方法。
4. 裝飾器
裝飾器是一種設(shè)計(jì)模式,它支持?jǐn)U展函數(shù)的屬性而無(wú)需編輯函數(shù)本身。這可能聽(tīng)起來(lái)很復(fù)雜,但在實(shí)際操作中非常簡(jiǎn)單。想象一下,你想測(cè)量函數(shù)的執(zhí)行時(shí)間,可以編寫類似下面的代碼:
import time
start_time = time.time()
main()
print("--- %s seconds ---" % (time.time() - start_time))
# --- 0.764891862869 seconds ---
但是,如果想要測(cè)試其他函數(shù)的時(shí)間,就必須創(chuàng)建重復(fù)的代碼。為了解決這個(gè)問(wèn)題,可以向想要計(jì)時(shí)的函數(shù)添加一個(gè)裝飾器:
from time import time
def timer_func(func): # 接受函數(shù)作為參數(shù)
def wrap_func(*args, **kwargs):
t1 = time() # 初始時(shí)間
result = func(*args, **kwargs)
t2 = time() # 結(jié)束時(shí)間
print(t2 - t1) # 時(shí)間差(以秒為單位)
return result
return wrap_func
@timer_func # 我們編寫的裝飾器
def long_time(n):
# 這個(gè)函數(shù)會(huì)花一些時(shí)間
for i in range(n):
for j in range(n):
i*j
long_time(10_000)
# 3.2696526050567627
現(xiàn)在,該裝飾器也可以在其他函數(shù)中重復(fù)使用!
Python還內(nèi)置了裝飾器,例如functools模塊中的裝飾器。可以在如下文章中找到其他有用的內(nèi)置裝飾器。
《代碼減半,5個(gè)絕佳的Python裝飾器》
5. 壓縮和解壓縮
zip是一個(gè)可以將列表合并為元組的函數(shù)。以下是一個(gè)簡(jiǎn)單的示例,可以輕松地遍歷兩個(gè)不同的列表:
firstNames = ["John", "Adam", "Steve", "Alan", "Extra"]
lastNames = ["Lennon", "Smith", "Jobs", "Turing"]
for first, last in zip(firstNames,lastNames):
print(first, last)
'''
John Lennon
Adam Smith
Steve Jobs
Alan Turing
'''
注意額外的名字是如何被省略的。zip的長(zhǎng)度與最短列表的長(zhǎng)度相同。
如果想要獲取一個(gè)元組列表中的所有首元素,zip也很有用。例如,如果你有一個(gè)(包含Name, Age, Gender)列表,但只想獲得Name的列表,可以按以下方式編寫代碼:
names = [('Joe', 12, "male"),
('Earnst', 43, "male"),
('Anna', 65, "female"),
('Martin', 39, "male"),
('Katie', 26, "female")]
name, age, gender = zip(*names)
print(name)
# ('Joe', 'Earnst', 'Anna', 'Martin', 'Katie')
綜上所述,這些是Python中的五個(gè)基本技巧。如果想了解更多技巧,可以閱讀本文最后的精彩回顧。