Categories
程式開發

這5個Python特性,後悔沒早知道


這5個Python特性,後悔沒早知道 1

作為近10年才崛起的編程語言,Python已被證明是一種非常強大的語言。從交互式映射區塊鏈,我用Python構建過很多應用程序。

對初學者而言,Python中有很多特性很難一開始就掌握。

即使你是從其他語言轉換過來的程序員,用Python進行更高級別的抽象編碼絕對是另一種體驗。有些Python特性,我希望自己能早點知道。本文將介紹其5個最重要的特性。

1.列表推導式:代碼更緊湊

很多人認為,lambda、mapfilter是初學者應該最先掌握的Python“技巧”。雖然我也認為應關注這些功能,但由於它們缺乏靈活性。

實際上,它們在大多數情況下並不是非常有用!

Lambda是一種在1行中編寫一個一次性使用的函數的方法。一旦函數被多次調用,性能將受到影響。

另一方面,map 可以將一個函數應用於列表中的所有元素,而 filter 能獲取集合中滿足用戶自定義條件的元素子集。

add_func = lambda z: z ** 2
is_odd = lambda z: z%2 == 1
multiply = lambda x,y: x*y

aList = list(range(10))
print(aList)
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

列表推導式是一個簡潔而靈活的方法,它使用靈活的表達式和條件通過其他列表來創建新列表。

它用方括號來構造,帶有一個表達式或函數,只有當列表中的元素滿足某個條件時,該表達式或函數才作用於列表中的每個元素。

並且,它還能用嵌套來處理嵌套列表,並且這會比使用 map 和 filter 更靈活。

# Syntax of list comprehension
( expression(x) for x in aList if optional_condition(x) )
print(list(map(add_func, aList)))
print((x ** 2 for x in aList))
# (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
# (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

print(list(filter(is_odd, aList)))
print((x for x in aList if x%2 == 1))
# (1, 3, 5, 7, 9)
# (1, 3, 5, 7, 9)

下載地址:python-list-comprehension.py

2、列表操作:實現列表的雙向操作

Python 允許使用反向索引,其中aList(-1) == aList(len(aList)-1) 。所以,我們可以通過調用aList(-2) 來獲取列表的倒數第二個元素。

我們還能使用aList(start:end:step)語法來對列表進行切片,其中起始元素包含在內,終止元素不包含在內(即(start,end) 步長為step 的前閉後開區間)。

因此,調用 aList(2:5) 會得到 (2, 3, 4)。我們也能通過調用 aList(::-1) 來反轉列表,這種技術非常優雅。

此外,也可以將列表拆分成單獨的元素,或者使用星號將列表拆分成單個元素和子列表的混合形式。

a, b, c, d = aList(0:4)
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = 1, c = 2, d = 3

a, *b, c, d = aList
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = (1, 2, 3, 4, 5, 6, 7), c = 8, d = 9

下載地址:python-unpacking.py

3、 壓縮和枚舉:for 循環更方便

Zip 函數會創建一個迭代器,且該迭代器可以對來自多個列表的元素進行聚合。用它可以在 for 循環中對列表進行並行遍歷和排序。

用星號對其進行解壓。

numList = (0, 1, 2)
engList = ('zero', 'one', 'two')
espList = ('cero', 'uno', 'dos')
print(list(zip(numList, engList, espList)))
# ((0, 'zero', 'cero'), (1, 'one', 'uno'), (2, 'two', 'dos'))

for num, eng, esp in zip(numList, engList, espList):
    print(f'{num} is {eng} in English and {esp} in Spanish.')
# 0 is zero in English and cero in Spanish.
# 1 is one in English and uno in Spanish.
# 2 is two in English and dos in Spanish.

下載地址:python-zip-1.py

Eng = list(zip(engList, espList, numList))
Eng.sort() # sort by engList
a, b, c = zip(*Eng)

print(a)
print(b)
print(c)
# ('one', 'two', 'zero')
# ('uno', 'dos', 'cero')
# (1, 2, 0)

下載地址:python-zip-2.py

開始時, Enumerate 看起來有點嚇人,但在很多情況下使用它確實能方便很多。

它是一個自動計數器,通常會在 for 循環中使用它,這樣就不需要再用 counter = 0counter += 1 來創建和初始化計數器了。枚舉和壓縮是兩個構造 for 循環的最強工具。

upperCase = ('A', 'B', 'C', 'D', 'E', 'F')
lowerCase = ('a', 'b', 'c', 'd', 'e', 'f')
for i, (upper, lower) in enumerate(zip(upperCase, lowerCase), 1):
    print(f'{i}: {upper} and {lower}.')
# 1: A and a.
# 2: B and b.
# 3: C and c.
# 4: D and d.
# 5: E and e.
# 6: F and f.

下載地址:python-enumerate.py

4、生成器:內存更高效

當我們想要對一個大的結果集進行計算,但又不想為所有結果數據同時分配內存時,我們就可以使用生成器(Generator)了。

換句話說,它會動態地生成值,並且不會將先前的值存儲在內存中,因此我們只能對它們進行一次迭代操作。

當讀取大文件或使用關鍵字 yield 生成無窮數列時,通常會用它。我發現在我的大多數數據科學項目中,它都能發揮很大作用。

def gen(n):    # an infinite sequence generator that generates integers >= n
    while True:
        yield n
        n += 1
        
G = gen(3)     # starts at 3
print(next(G)) # 3
print(next(G)) # 4
print(next(G)) # 5
print(next(G)) # 6

下載地址:python-generator.py

5、虛擬環境:實現隔離

如果在本文介紹的5個特性中只選一個,那麼就是虛擬環境的使用。

Python 應用程序通常會用各種不同的包,這些包可能是由具有復雜依賴關係的不同開發人員開發的。每個應用程序都會用特定的庫設置,使用其他庫的版本無法實現對某個應用程序安裝包的複制。

所以,不存在滿足所有應用要求的單個安裝包。

conda create -n venv pip python=3.7  # select python version
source activate venv
...
source deactivate

為每個應用程序創建獨立的、自洽的虛擬環境 venv 非常重要,這可以通過使用 pipconda來實現。

原文鏈接:

https://towardsdatascience.com/5-python-features-i-wish-i-had-known-earlier-bc16e4a13bf4