作者|Philip Wilkinson
編譯|VK
來源|Towards Datas Science
在使用Python將近一年的時間里,我經常遇到“生成式”這個詞,但我沒生成式它的確切含義或它所涵蓋的內容,
直到最近,我才發現,有了生成式后,我可以利用串列將我的代碼從多行縮短為一行,此外,這種代碼縮短方法不僅可以用于串列,還可以用于字典和集合,
本文試圖解釋生成式在串列、字典和集合的適用性,以及它們如何減少日常編程所需的代碼量,
首先,生成式是可以在一行中創建串列、字典和集合的代碼片段,這樣就不必為for回圈使用多行,而且還減少了使用map()、filter()和reduce()函式的需要,
它們由方括號(根據你要創建的資料型別而定)組成,其中包含一個運算式,后跟一個for子句和一個或多個if子句,運算式本身可以是任何東西,這意味著你可以將許多不同的物件放入串列中,只要它們是可編輯的,因此,從減少使用的行數和增加可讀性的角度來探討這些可能對代碼產生的影響是值得的,
串列
在python中,只需將專案放在方括號([])內,用逗號分隔,就可以創建串列,如下所示,
list1 = [1, 2, 3, "hello", 7.0, 52]
它們通常用于多種目的的編程中,但在長格式中撰寫或使用for回圈進行編輯都會很麻煩,首先,在創建串列方面,小串列可能很容易以長格式列印出來,例如:
nums = [1, 2, 3, 4, 5, 6, 7, 8]
但當這個值變長時,即在0-50范圍內,甚至更長,它們可能會變得笨重,它們可以通過for回圈使用range函式輕松創建,如下所示:
nums = []
for i in range(1, 51):
nums.append(i)
print(nums)
# out: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
但是我們可以使用串列生成式將其縮短為一行,并且不需要append()方法,
nums = [i for i in range(1,51)]
print(nums)
# out: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
基本上,for回圈放在一行中,同時初始化串列,從上面的示例中消除了對第一行和第二行代碼的需要,
當我們開始為添加到串列中的數字添加條件時,這就變得更加重要了,比如只允許偶數并且希望這些數字是平方的,同樣,也可以使用for回圈生成,如下所示:
square_nums = []
for x in range(1,26):
if x % 2 == 0:
square_nums.append(x**2)
print(square_nums)
# out: [4, 16, 36, 64, 100, 144, 196, 256, 324, 400, 484, 576]
但是,同樣可以使用串列生成式將其縮短為一行,從而減少對用于在范圍內回圈、創建條件并將結果附加到原始串列的行的需要,
square_nums = [x**2 for x in range(1,26) if x % 2 == 0]
print(square_nums)
#out: [4, 16, 36, 64, 100, 144, 196, 256, 324, 400, 484, 576]
在這里,數字的轉換在行首執行x**2,for回圈在行中執行,對于x在范圍(1,26),條件在末尾執行,就好像x%2==0一樣,這本質上使代碼更具可讀性,因為所有操作都在一行中執行,并減少了生成相同輸出所需的代碼量,
這還可以減少append()、map()、filter()或reduce()方法在創建新串列時對現有串列進行操作的需要,再次降低代碼的復雜性并使其更具可讀性,
類似的例子是很容易獲得的,更多的資訊可以很容易地通過其他文章在媒介,如這里和這里獲得,然而,值得注意的是,這些生成式也可以用于字典和集合,
字典
字典是一個無序的資料集合,可以改變和索引,使用大括號和鍵和值對撰寫,在這里,鍵被用來訪問值,并且經常被用來存盤資訊,這些資訊對這些資訊是有用的,下面提供了一個示例,例如用于存盤分數,
Grades = {
"Steven": 57,
"Jessica": 82,
"William": 42,
"Hussein": 78,
"Mary": 65,
}
print(Grades)
# out: {'Steven': 57, 'Jessica': 82, 'William': 42, 'Hussein': 78, 'Mary': 65}
與串列類似,有時也會很耗時,因此可以使用for回圈和條件陳述句來構造,但可以更簡單地使用生成式來構造,
例如,對于我們在上面創建的串列,我們不僅想知道數字的平方,而且還想存盤原始數字,這樣我們就可以使用它輕松地查找它的平方值,然后,我們可以簡單地創建一個包含鍵值對的字典,其中key代表原始數字,value代表數字的平方,使用for回圈:
#初始化空dict
even_squared_dict = {}
for x in range(1,10):
if x % 2 == 0:
even_squared_dict[x] = x**2
print(even_squared_dict)
# out: {2: 4, 4: 16, 6: 36, 8: 64}
但是使用字典生成式:
even_sqaured_dict = {x: x**2 for x in range(1,10) if x % 2 ==0}
print(even_squared_dict)
# out: {2: 4, 4: 16, 6: 36, 8: 64}
本質上,這個和串列生成式之間的唯一區別是使用大括號來包含生成式,并將x放在冒號前面,以指示這表示鍵,
然后,還可以使用它來創建基于現有串列的字典,例如下面,字典生成式用于創建一個字典,其鍵為三位數的國家代碼,值為兩位數的國家代碼,其中兩位數代碼與三位數代碼的前兩位數相同,
ThreeCharCodes = ["CAN", "FIN", "FRA", "GAB", "HKG", "IMN",
"MCO", "NPL"]
cntryDict = {c: c[:2] for c in threeCharCodes}
print(cntryDict)
# out: {'CAN': 'CA', 'FIN': 'FI', 'FRA': 'FR', 'GAB': 'GA', 'HKG': 'HK', 'IMN': 'IM', 'MCO': 'MC', 'NPL': 'NP'}
集合
最后,生成式也可以用于創建集合,集合是一種不同于串列或元組的資料型別,不能存盤同一元素的多次出現,
在這樣做時,它存盤無序值,初始化方法是將一個串列傳遞給set()或使用大括號來包含由逗號分隔的值(盡管空的花括號將初始化字典),下面提供了一個例子:
Fruits1 = set(["apple", "banana", "cherry", "apple"])
print(Fruits1)
Fruits2 = {"orange", "pear", "grape", "pear"}
print(Fruits2)
# out: {'apple', 'cherry', 'banana'}
{'grape', 'pear', 'orange'}
從這里可以清楚地看到,盡管向集合傳遞了多個apple或pear值,但只生成了一個實體,同樣,可以使用for回圈生成這些命令,如下所示:
import random
nums = set([])
for x in range(25):
y = random.randint(10,20)
nums.add(y)
print(nums)
# out: {10, 12, 14, 15, 16, 17, 18, 20}
雖然25個隨機整數在10-20之間,但最終輸出僅包含8個唯一值,而不是串列中出現的25個值,同樣,使用對集合的生成式可以更簡潔地撰寫這篇文章,
nums = {random.randint(10,20) for num in range(25)}
print(nums)
# out: {11, 12, 13, 14, 15, 16, 17, 19, 20}
因此,這種生成式與串列生成式的區別在于使用大括號,而不是包含生成式的方括號,
與串列和字典生成式類似,這也可以用于現有串列以生成集合,例如,如果我們想根據1.6的除法將公里改為英里,只需要唯一的值,并將其限制為小于100公里的值,
kms = [10, 12, 65, 40, 12, 75, 34, 65, 10, 10, 38, 100, 160, 200]
miles = {d/1.6 for d in kms if d < 100}
print(miles)
# out: {0.625, 0.75, 2.5, 2.125, 4.0625, 4.6875, 2.375}
總結
因此,生成式可以很容易地用于創建新的串列、詞典和集合,使用這些可以減少生成它們所需的行數,并提高可讀性,它們可以用作append()、map()、filter()或reduce()函式的替換,
顯然,可以將它們放大以執行更復雜的生成式,例如使用lambda函式、嵌套串列生成式或多條件陳述句,然而,在這樣做時值得注意的是,生成式可能很快變得難以理解,在這種情況下,值得回到創建函式或for回圈,以便在需要執行多個操作時提高可讀性,
原文鏈接:https://towardsdatascience.com/the-use-of-list-dictionary-and-set-comprehensions-to-shorten-your-code-66e6dfeaae13
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/158109.html
標籤:其他
上一篇:向量化代碼
下一篇:向量化代碼
