分享九個一般人不知道的Python好用技巧
本篇分享是Python生態系統中關于一些有用的技巧。大多數技巧只是使用標準庫中的包,但其他一些技巧會涉及一些第三方包。
在開始閱讀本文內容之前,我們首先來回顧一下Python中的Iterables的概念。
根據Python標準文檔,Iterable的概念如下:
- 一種能夠一次返回一個成員的對象。
iterables的示例包括:
- 所有序列類型(如list、str和tuple)
- 一些非序列類型,如dict、文件對象以及類的實現中定義了__iter__()方法
Iterables是一個需要我們牢記的概念,因為接下來我們展示的許多技巧都使用itertools包。
itertools模塊提供了一些函數,用于接收Iterable對象,而不僅僅是打印逐個對象。
2.Trick 1
在工作學習中,我們經常會需要使用一個簡單的函數來實現從一個list來生成新的list,set或dict.此時我們就會用到iterables概念。
舉例來說:
生成List:
- names = ['John', 'Bard', 'Jessica' 'Andres']
- lower_names = [name.lower() for name in names]
生成Set:
- names = ['John', 'Bard', 'Jessica' 'Andres']
- lower_names = {
- name.lower() for name in names}
生成Dict:
- names = ['John', 'Bard', 'Jessica' 'Andres']
- lower_names = {
- name:name.lower() for name in names}
個人建議:
僅當for語句、函數調用和方法調用的數量較少時使用。
3.Trick 2
有時,我們需要獲得兩個列表對象之間的所有可能組合。
我們首先想到的實現可能如下:
- l1 = [1, 2, 3]
- l2 = [4, 5, 6]
- combinations = []
- for e1 in l1:
- for e2 in l2:
- combinations.append((e1, e2))
或者簡化一下,如下:
- combinations = [(e1, e2) for e1 in l1 for e2 in l1]
上述實現已經很簡潔了,但標準庫itertools提供product函數,從而提供了相同的結果。如下所示:
- from itertools import product
- l1 = [1, 2, 3]
- l2 = [4, 5, 6]
- combinatios = product(l1, l2)
4.Trick3
假設有一個元素列表,我們需要在每對相鄰元素之間比較或應用一些操作,這有時稱為2個元素的滑動窗口。我們可以采用以下方式:
- from itertools import tee
- from typing import Iterable
- def window2(iterable: Iterable):
- it, offset = tee(iter(iterable))
- next(offset)
- return zip(it, offset)
- l = [1, 2, 3, 4, 5, 6]
- dd = window2(l)
- for a in dd:
- print(a)
運行結果如下:
- (1, 2)
- (2, 3)
- (3, 4)
- (4, 5)
- (5, 6)
5.Trick4
有時,我們會需要一個類來存儲信息,但是如果我們覺得創建一個類并定義其__init__()函數太麻煩時,我們不妨選擇使用dataclass。如下所示:
- from dataclasses import dataclass
- @dataclass
- class Person:
- name: str
- age: int
- address: str
上述代碼創建了一個具有默認構造函數的類,該類以與聲明相同的順序接收相應字段的賦值。
- person = Person(name='John', age=12, address='nanjing street')
dataclass的另一個優點是,默認情況下,會生成特殊方法,如__str__、 repr 、__eq__等。關于dataclass的更多用法,可以 參考官網 。
值得一提的是我們在類中聲明的成員變量的類型注釋(str、int等)并不強制在構造函數中傳遞的值屬于這種類型。也就是說dataclasses構造對象時并不執行數據類型的檢查。
6.Trick5
我們有時希望將一個對象上的操作視為tuple上的操作,一種選擇是使用collections.namedtuple,但也存在更類似于dataclass的實現。如下:
- from typing import NamedTuple
- class Coordinate(NamedTuple):
- x: int
- y: int
上述定義了一個標準的類可以被當做tuple來使用,如下:
- coordinate = Coordinate(10, 15)
- coordinate.x == coordinate[0] // True
- coordinate.y == coordinate[1] // True
7.Trick6
假如我們有一個dataclass,需要驗證輸入數據是否符合類型注釋。在這種情況下,安裝第三方軟件包pydantic并將
from dataclasses import dataclass 替換為 from pydantic.dataclasses import dataclass 即可,如下:
- from pydantic.dataclasses import dataclass
- @dataclass
- class Person:
- name: str
- age: int
- address: str
這將生成一個類,該類具有根據成員變量聲明的類型進行輸入數據的解析和類型驗證。 Pydantic 在運行時強制執行類型提示,并在數據無效時提供友好的錯誤提醒。
8.Trick7
在某些情況下,我們需要生成一些容器中元素頻率的基本統計信息。在這種情況下,您可以使用標準結構Counter來接收iterable并根據元素的頻率生成相應的統計信息。
- from collections import Counter
- l = [1, 1, 2, 3, 4, 4]
- frequencys = Counter(l)
- print(frequencys[1]) // Ouput: 2
- print(frequencys[2]) // Ouput: 1
- print(frequencys[2323]) // Ouput: 0
Counter也提供了一些其他方法,比如如most_common,用于檢索最常見的元素。
9.Trick8
如果我們相對兩個list中的元素對做相應的函數處理,我們最容易想到的方法如下:
- l1 = [1, 2, 3]
- l2 = [4, 5, 6]
- for (e1, e2) in zip(l1, l2):
- f(e1, e2)
但是使用函數map可以讓代碼更加簡潔一些。
- l1 = [1, 2, 3]
- l2 = [4, 5, 6]
- map(f, l1, l2)
10.Trick9
有時候我們需要從一個list中隨機選擇一個元素,此時我們使用random.choice.如下所示:
- from random import choice
- l = [1, 2, 3]
- random = choice(l)
如果我們需要隨機選擇多個元素呢?當然是使用random.choices.
- from random import choices
- l = [1, 2, 3, 4, 5]
- random_elements = choices(l, k=3)
上述代碼中的參數k為我們隨機選擇元素的個數。
11.總結
本文重點介紹了在python中9個和迭代相關的使用技巧,可以方便提升大家的工作效率。
您學廢了嗎?