Python五個隱藏的特性,你可能從未聽說過
前言
在本文中,我將向您展示Python中很常見的5個特性。有經(jīng)驗的Python開發(fā)人員可能認識其中一些。然而,這對其他人仍將是未知的。
1...
是的,你沒看錯,在Python中...是一個有效的構(gòu)造。...是稱為省略號的單例對象。如果你把它輸入到Python解釋器中,你可以看到它:
- >>> ...
- Ellipsis
根據(jù)官方文檔,省略號是“一種特殊值,主要與用戶定義容器數(shù)據(jù)類型的擴展切片語法結(jié)合使用”。它有兩個主要的用例。一種是在空函數(shù)中充當(dāng)占位符體。另一個是Numpy,作為一個切片項,就像文檔中描述的那樣。
函數(shù)的占位符
- def my_awesome_function():
- ...
這相當(dāng)于:
- def my_awesome_function():
- Ellipsis
還有這個:
- def my_awesome_function():
- pass
注意,我不是說pass =…我只是說作為函數(shù)體,結(jié)果是一樣的。事實上,您可以使用任何東西作為占位符。
Numpy
下面的代碼基本上意味著創(chuàng)建一個矩陣數(shù)組。每個矩陣是3×3。然后獲取所有最內(nèi)部矩陣的第二列(numpy數(shù)組基于0)。
- import numpy as np
- >>> array = np.arange(27).reshape(3, 3, 3)
- >>> array
- array([[[ 0, 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]]])
- >>> array[..., 1]
- array([[ 1, 4, 7],
- [10, 13, 16],
- [19, 22, 25]])
- >>> # This is equivalent to
- >>> array[:, :, 1]
- array([[ 1, 4, 7],
- [10, 13, 16],
- [19, 22, 25]])
2一個優(yōu)雅的解包
可迭代解包是一種非常方便的特性,已經(jīng)存在一段時間了。大多數(shù)人使用它來解包包含多個項的可迭代對象。例如,考慮以下用例。
- >>> a, *b, c = range(1, 11)
- >>> a
- 1
- >>> c
- 10
- >>> b
- [2, 3, 4, 5, 6, 7, 8, 9]
或者是:
- >>> a, b, c = range(3)
- >>> a
- 0
- >>> b
- 1
- >>> c
- 2
但有一個很好的用例,很多人都沒有利用它,那就是拆封單個迭代器。為什么這很有用?恕我直言,它使代碼更優(yōu)雅了一些。
而不是這樣做:
- >>> lst = [1]
- >>> a = lst[0]
- >>> a
- 1
- >>> (a, ) = lst
- >>> a
- 1
你可以這樣做:
- >>> lst = [1]
- >>> [a] = lst
- >>> a
- 1
我知道這可能看起來很傻,但至少對我來說,它看起來更優(yōu)雅。
3你能讓這個列表躺平嗎?
扁平化列表有幾種方法。最簡單的是使用列表理解。
- >>> l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
- >>> flattened = [elem for sublist in l for elem in sublist]
- >>> flattened
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
如果您更傾向于函數(shù)式編程,您可以使用減速器。
- >>> from functools import reduce
- >>> reduce(lambda x,y: x+y,l)
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
然而,還有另一種方法。你可以用sum函數(shù)!
- >>> sum(l, [])
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
這是因為sum函數(shù)遍歷列表中的每個元素,并將它們與作為第二個參數(shù)傳遞的默認值連接起來。因為Python中的列表可以用+操作符連接,所以你得到的結(jié)果是這樣的:
- >>> sum(l, []) ==> [] + [1, 2, 3] + [4, 5, 6] + [7, 8, 9]
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
盡管這個技巧很高明,但它絕不是可讀的。而且,它的性能也很糟糕。
4else
else語句可以用于幾個目的。很少有人知道,但是你可以在經(jīng)典的“if else”塊之外使用它。Python允許它用于循環(huán)和異常塊。
循環(huán)
Python有兩個不同的循環(huán),for和while。兩者都可能是“壞的”。也就是說,如果滿足了某個條件,就可以跳出循環(huán)。例如:
- In [7]: while a < 10:
- ...: if a == 3:
- ...: print("a == 3. exiting loop.")
- ...: break
- ...: a += 1
- ...:
- a == 3. exiting loop.
現(xiàn)在,假設(shè)我們要找一個特定的條件。如果滿足該條件,則將結(jié)果保存在一個名為found的標(biāo)志中。然后,如果我們沒有找到它,我們打印一條消息。
- found = False
- a = 0
- while a < 10:
- if a == 12:
- found = True
- a += 1
- if not found:
- print("a was never found")
因為a永遠不會變成12,所以程序輸出a永遠不會找到。
好,但是我們在這里怎么用else呢?
else可以用來替換標(biāo)志。基本上,我們實際需要的是運行循環(huán),如果沒有找到,則打印一條消息。
- a = 0
- while a < 10:
- if a == 12:
- break
- a += 1
- else:
- print("a was never found")
由于它適用于任何循環(huán),所以您可以使用for而不是while。
- for a in range(10):
- if a == 12:
- break
- a += 1
- else:
- print("a was never found")
異常
Python中的else是如此通用,你甚至可以使用try…except。這里的思想是捕獲異常不發(fā)生的情況。
- In [13]: try:
- ...: {}['lala']
- ...: except KeyError:
- ...: print("Key is missing")
- ...: else:
- ...: print("Else here")
- ...:
- Key is missing
在這個例子中,我們嘗試在一個空字典中查找名為“lala”的鍵。由于“lala”不存在,代碼將引發(fā)一個KeyError異常。當(dāng)我在IPython中運行這段代碼時,得到了預(yù)期的結(jié)果。
如果程序沒有引發(fā)異常呢?
- In [14]: try:
- ...: {'lala': 'bla'}['lala']
- ...: except KeyError:
- ...: print("Key is missing")
- ...: else:
- ...: print("Else here")
- ...:
- Else here
現(xiàn)在我們可以看到它的實際應(yīng)用。{' lala ': ' bla '}[' lala ']塊不會引發(fā)KeyError,所以else就起作用了。
5比較
這是我最喜歡的一個,老實說,沒有那么隱蔽。與許多編程語言(如Java、C或c++)不同,Python允許鏈?zhǔn)奖容^運算符。假設(shè)你有一個變量x,它的值是10。現(xiàn)在,假設(shè)你想斷言x在一個范圍內(nèi),比如5..20。你可以這樣做:
- In [16]: x = 10
- In [17]: if x >= 5 and x <= 20:
- ...: print("x is within range")
- ...: else:
- ...: print("x is outside range")
- ...:
- is within range
事實證明,這可以通過將運算符鏈接起來來簡化。所以,我們可以重構(gòu)代碼為:
- In [18]: if 5 <= x <= 20:
- ...: print("is within range")
- ...: else:
- ...: print("x is outside range")
- ...:
- is within range
這段代碼實現(xiàn)了完全相同的結(jié)果,但它更加優(yōu)雅。您可以使用任何一種比較運算符進行鏈。
- >>> x = 10
- >>> 20 == x > 1
- False
- >>> 25 > x <= 15
- True
- >>> x < 20 < x*10 < 1000
- True