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