文章目錄
- 前言
- Python之禪
- Python:優雅高效的寫法
- 多變量賦值
- 變量交換
- 格式化字符串
- 序列并包(pack)
- 序列解包(unpack)
- 條件表達式
- if結構簡化
- if鏈式條件表達式
- any & all
- eval
- 遍歷元素與下標
- for/else
- dict映射代替多條件查找
- 訪問字典元素
- defaultdict
- 列表/字典解析式
- 字符串連接
- "_"的妙用
- map函數
- reduce函數
- filter函數
- 生成器(generator)
- yield
- partial函數
- lru_cache
- 枚舉
- Reference
前言
目前Python已經更新到了3.7版本,不必多說,Python 3比Python 2更是多出了許多新的功能。Python是一門友好的語言,其區別于以往C++,Java的特點不僅是代碼易于閱讀,同時代碼也更加優雅簡潔,實現同樣的功能相對于Python只需要短短幾行代碼,這給予了開發人員更大的便利,同時也易于初學者學習。本文將介紹Python中一些有趣實用的(代碼)功能,希望這些代碼能夠幫助大家更加輕松優雅地解決一些問題。
注:本博客代碼結果均為Python 3.6版本運行結果
Python之禪
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea – let’s do more of those!
Python之禪 by Tim Peters
優美勝于丑陋(Python以編寫優美的代碼為目標)
明了勝于晦澀(優美的代碼應當是明了的,命名規范,風格相似)
簡潔勝于復雜(優美的代碼應當是簡潔的,不要有復雜的內部實現)
復雜勝于凌亂(如果復雜不可避免,那代碼間也不能有難懂的關系,要保持接口簡潔)
扁平勝于嵌套(優美的代碼應當是扁平的,不能有太多的嵌套)
間隔勝于緊湊(優美的代碼有適當的間隔,不要奢望一行代碼解決問題)
可讀性很重要(優美的代碼是可讀的)
即便假借特例的實用性之名,也不可違背這些規則(這些規則至高無上)
不要包容所有錯誤,除非您確定需要這樣做(精準地捕獲異常,不寫 except:pass 風格的代碼)
當存在多種可能,不要嘗試去猜測
而是盡量找一種,最好是唯一一種明顯的解決方案(如果不確定,就用窮舉法)
雖然這并不容易,因為您不是 Python 之父(這里的 Dutch 是指 Guido )
做也許好過不做,但不假思索就動手還不如不做(動手之前要細思量)
如果您無法向人描述您的方案,那肯定不是一個好方案;反之亦然(方案測評標準)
命名空間是一種絕妙的理念,我們應當多加利用(倡導與號召)
Python:優雅高效的寫法
多變量賦值
當你想要初始化多個變量的時候:
- Bad
x
=
[
]
y
=
[
]
z
=
[
]
- Better
x
,
y
,
z
=
[
]
,
[
]
,
[
]
這樣做的話代碼更加簡潔,同時可讀性更高
變量交換
- Bad
# edchange x and y
t
=
x
x
=
y
y
=
t
- Better
# edchange x and y
x
,
y
=
y
,
x
這樣做的話不止代碼簡潔,讓人一眼就能看出是要交換變量,同時也能免去考慮中間變量賦值的先后順序,并且后者的效率更是高于前者。
格式化字符串
如果你想要格式化輸出一串字符串,你會怎么做?
- Bad
name
=
"James"
country
=
"USA"
string
=
"My name is %s, from %s, I love %s"
%
(
name
,
country
,
country
)
>>
>
string
'My name is James, from USA, I love USA'
- Better
name
=
"James"
country
=
"USA"
string
=
"My name is {}, from {}, I love {}"
.
format
(
name
,
country
,
country
)
>>
>
string
'My name is James, from USA, I love USA'
- Best
name
=
"James"
country
=
"USA"
string
=
"My name is {name}, from {country}, I love {country}"
.
format
(
name
=
name
,
country
=
country
)
'My name is James, from USA, I love USA'
# or you can simplipy it by using f-strings
name
=
"James"
country
=
"USA"
string
=
f
"My name is {name}, from {country}, I love {country}"
>>
>
string
'My name is James, from USA, I love USA'
使用
format
函數比使用
%s
可讀性更高,同時也更易于控制輸出格式。
序列并包(pack)
當你想同時訪問兩個列表的時候,你的做法是?
- Bad
names
=
[
'James'
,
'Tim'
,
'Katty'
]
ages
=
[
18
,
19
,
20
]
for
i
in
range
(
len
(
names
)
)
:
print
(
"name:"
,
names
[
i
]
,
"age:"
,
ages
[
i
]
)
name
:
James age
:
18
name
:
Tim age
:
19
name
:
Katty age
:
20
- Better
names
=
[
'James'
,
'Tim'
,
'Katty'
]
ages
=
[
18
,
19
,
20
]
for
name
,
age
in
zip
(
names
,
ages
)
:
print
(
"name:"
,
name
,
"age:"
,
age
)
name
:
James age
:
18
name
:
Tim age
:
19
name
:
Katty age
:
20
后者的方法不僅一目了然,同時遍歷元素的行為比遍歷下標的行為更加高效!
序列解包(unpack)
當你需要將一個二元組序列拆成兩列,你會怎么做?
- Bad
Data
=
[
(
'James'
,
18
)
,
(
'Tim'
,
19
)
,
(
'Katty'
,
20
)
]
names
,
ages
=
[
]
,
[
]
for
name
,
age
in
Data
:
names
.
append
(
name
)
ages
.
append
(
age
)
- Better
Data
=
[
(
'James'
,
18
)
,
(
'Tim'
,
19
)
,
(
'Katty'
,
20
)
]
names
=
[
data
[
0
]
for
data
in
Data
]
ages
=
[
data
[
1
]
for
data
in
Data
]
- Best
Data
=
[
(
'James'
,
18
)
,
(
'Tim'
,
19
)
,
(
'Katty'
,
20
)
]
names
,
ages
=
zip
(
*
Data
)
zip()
和
zip(*)
是一對互逆操作,不過需要注意,
zip()
和
zip(*)
在Python 3返回的都是迭代器,然后
zip(*)
通過解包返回多個元組。
條件表達式
- Bad
if
x
<
y
:
small
=
x
else
:
small
=
y
- Better
small
=
x
if
x
<
y
else
y
后者不僅表達意思更加明了,同時代碼量也少了好幾行。
if結構簡化
如果你需要檢查幾個數值時:
- Bad
if
x
==
1
or
x
==
2
or
x
==
3
or
x
==
4
:
print
(
"x =1 or 2 or 3 or 4"
)
- Better
if
x
in
(
1
,
2
,
3
,
4
)
:
print
(
"x =1 or 2 or 3 or 4"
)
if鏈式條件表達式
- Bad
if
x
>
0
and
x
<
10
:
print
(
"0
<10"
)
- Better
if
0
<
x
<
10
:
print
(
"0
<10"
)
前者是其他語言的判斷方法,而后者顯然更加簡潔明了。
any & all
當存在多個條件判斷語句時:
- Bad
if
a
>
0
or
b
>
0
or
c
>
0
:
print
(
"one of them greater than 0"
)
if
a
>
0
and
b
>
0
and
c
>
0
:
print
(
"all of them greater than 0"
)
- Better
if
any
(
[
a
,
b
,
c
]
)
:
print
(
"one of them greater than 0"
)
if
all
(
[
a
,
b
,
c
]
)
:
print
(
"all of them greater than 0"
)
eval
eval
函數可以輕易的將字符串轉化成元素,甚至可以轉化表達式:
>>
>
eval
(
'[1,2,3,4]'
)
[
1
,
2
,
3
,
4
]
>>
>
eval
(
'(1,2,3,4)'
)
(
1
,
2
,
3
,
4
)
>>
>
eval
(
'1+1'
)
2
eval
功能可謂非常強大,即可以做
string
與
list
,
tuple
,
dict
之間的類型轉換,還可以做計算器使用。它可以對能解析的字符串都做處理,而不顧忌可能帶來的后果!所以說eval強大的背后,是巨大的安全隱患。
例如用戶惡意輸入下面的字符串:
open
(
r
'D://filename.txt'
,
'r'
)
.
read
(
)
__import__
(
'os'
)
.
system
(
'dir'
)
__import__
(
'os'
)
.
system
(
'rm -rf /etc/*'
)
那么
eval
就會不管三七二十一,顯示你電腦目錄結構,讀取文件,刪除文件……如果是格盤等更嚴重的操作,它也會照做不誤。因此,更加安全的做法是使用
ast.literal_eval
:
>>
>
ast
.
literal_eval
(
"__import__('os').system('dir')"
)
ValueError Traceback
(
most recent call last
)
<
ipython
-
input
-
95
-
788ef7e6407f
>
in
<
module
>
(
)
-
-
-
-
>
1
ast
.
literal_eval
(
"__import__('os').system('dir')"
)
~
\Anaconda3\lib\ast
.
py
in
literal_eval
(
node_or_string
)
83
return
left
-
right
84
raise
ValueError
(
'malformed node or string: '
+
repr
(
node
)
)
-
-
-
>
85
return
_convert
(
node_or_string
)
86
87
~
\Anaconda3\lib\ast
.
py
in
_convert
(
node
)
82
else
:
83
return
left
-
right
-
-
-
>
84
raise
ValueError
(
'malformed node or string: '
+
repr
(
node
)
)
85
return
_convert
(
node_or_string
)
86
ValueError
:
malformed node
or
string
:
<
_ast
.
Call
object
at
0x000001C9DBA145F8
>
當你試圖轉化一些"危險"的表達式時,它會阻止你執行并報錯。出于安全考慮,對字符串進行類型轉換的時候最好使用
ast.literal_eval
遍歷元素與下標
當你需要遍歷元素得同時,獲取元素的位置下標:
- Bad
names
=
[
'James'
,
'Tim'
,
'Katty'
]
for
i
in
range
(
len
(
names
)
)
:
print
(
"Id:{},name:{}"
.
format
(
i
,
names
[
i
]
)
)
Id
:
0
,
name
:
James
Id
:
1
,
name
:
Tim
Id
:
2
,
name
:
Katty
- Better
names
=
[
'James'
,
'Tim'
,
'Katty'
]
for
i
,
name
in
enumerate
(
names
)
:
print
(
"Id:{},name:{}"
.
format
(
i
,
names
[
i
]
)
)
Id
:
0
,
name
:
James
Id
:
1
,
name
:
Tim
Id
:
2
,
name
:
Katty
前者的代碼不僅難看,同時通過下標訪問元素比遍歷元素效率更低,而后者使用
enumerate
則優雅高效得多。
for/else
如果讓你判斷某個列表是否存在偶數,存在則輸出該偶數,若不存在任何偶數,則輸出"There are no even Numbers"
- Bad
# The variable exit_even_number is redundant
exit_even_number
=
False
for
i
in
[
1
,
3
,
5
,
7
,
9
]
:
if
i
%
2
==
0
:
print
(
"{} is even number"
.
format
(
i
)
)
exit_even_number
=
True
if
not
exit_even_number
:
print
(
"There are no even Numbers"
)
- Better
for
i
in
[
1
,
3
,
5
,
7
,
9
]
:
if
i
%
2
==
0
:
print
(
"{} is even number"
.
format
(
i
)
)
else
:
print
(
"There are no even Numbers"
)
前者多了一個
exit_even_number
變量,使得代碼顯得有點臃腫,而使用后者
for/else
則優雅得多。
dict映射代替多條件查找
- Bad
if
x
==
1
:
y
=
100
elif
x
==
2
:
y
=
200
elif
x
==
y
=
300
- Better
condition = {1:100, 2:200, 3:300}
y = condition[x]
訪問字典元素
訪問字典元素的方法想必大家都清楚,但是如果字典中不存在該鍵值對呢?
- Bad
>>
>
phone_number
=
{
'James'
:
123456
,
'Tim'
:
678910
,
'Katty'
:
111213
}
>>
>
phone_number
[
'James'
]
123456
>>
>
phone_number
[
'james'
]
KeyError Traceback
(
most recent call last
)
<
ipython
-
input
-
64
-
6f91c5f93ae0
>
in
<
module
>
(
)
1
phone_number
=
{
'James'
:
123456
,
'Tim'
:
678910
,
'Katty'
:
111213
}
-
-
-
-
>
2
phone_number
[
'james'
]
KeyError
:
'james'
- Better
>>
>
phone_number
=
{
'James'
:
123456
,
'Tim'
:
678910
,
'Katty'
:
111213
}
>>
>
phone_number
[
'James'
]
if
'james'
in
phone_number
else
"Not Found"
123456
>>
>
phone_number
[
'james'
]
if
'james'
in
phone_number
else
"Not Found"
'Not Found'
- Best
>>
>
phone_number
=
{
'James'
:
123456
,
'Tim'
:
678910
,
'Katty'
:
111213
}
>>
>
phone_number
.
get
(
'James'
,
"Not Found"
)
123456
>>
>
phone_number
.
get
(
'james'
,
"Not Found"
)
'Not Found'
defaultdict
當你的字典中,每一個鍵值對應的是一個列表時,如何使用
append
操作?
- Bad
my_dict
=
{
}
names
=
[
'James'
,
'Tim'
,
'Katty'
,
'James'
]
numbers
=
[
123456
,
678910
,
111213
,
456789
]
for
name
,
number
in
zip
(
names
,
numbers
)
:
if
name
in
my_dict
:
my_dict
[
name
]
.
append
(
number
)
else
:
my_dict
[
name
]
=
[
]
my_dict
[
name
]
.
append
(
number
)
>>
>
my_dict
{
'James'
:
[
123456
,
456789
]
,
'Tim'
:
[
678910
]
,
'Katty'
:
[
111213
]
}
from
collections
import
defaultdict
my_dict
=
defaultdict
(
list
)
names
=
[
'James'
,
'Tim'
,
'Katty'
,
'James'
]
numbers
=
[
123456
,
678910
,
111213
,
456789
]
for
name
,
number
in
zip
(
names
,
numbers
)
:
my_dict
[
name
]
.
append
(
number
)
>>
>
my_dict
defaultdict
(
list
,
{
'James'
:
[
123456
,
456789
]
,
'Tim'
:
[
678910
]
,
'Katty'
:
[
111213
]
}
)
后者使用
defaultdict
,省去了判斷字典中否存在某個鍵值對應的列表,使得代碼更加簡潔易懂。
default
還有
int
,
tuple
等類型。
2. Better
my_dict
=
{
}
names
=
[
'James'
,
'Tim'
,
'Katty'
,
'James'
]
numbers
=
[
123456
,
678910
,
111213
,
456789
]
for
name
,
number
in
zip
(
names
,
numbers
)
:
if
name
in
my_dict
:
my_dict
[
name
]
.
append
(
number
)
else
:
my_dict
[
name
]
=
[
]
列表/字典解析式
當你想要生成一個列表或者字典的時候:
- Bad
生成列表
my_list
=
[
]
for
i
in
range
(
10
)
:
my_list
.
append
(
i
*
i
)
>>
>
my_list
[
0
,
1
,
4
,
9
,
16
,
25
,
36
,
49
,
64
,
81
]
生成字典
my_dict
=
{
}
for
i
in
range
(
10
)
:
my_dict
[
i
]
=
i
*
i
>>
>
my_dict
{
0
:
0
,
1
:
1
,
2
:
4
,
3
:
9
,
4
:
16
,
5
:
25
,
6
:
36
,
7
:
49
,
8
:
64
,
9
:
81
}
- Better
生成列表
>>
>
[
i
*
i
for
i
in
range
(
10
)
]
[
0
,
1
,
4
,
9
,
16
,
25
,
36
,
49
,
64
,
81
]
生成字典
>>
>
{
i
:
i
*
i
for
i
in
range
(
10
)
}
{
0
:
0
,
1
:
1
,
2
:
4
,
3
:
9
,
4
:
16
,
5
:
25
,
6
:
36
,
7
:
49
,
8
:
64
,
9
:
81
}
列表/字典推導式是Python獨具特色的功能之一,使用可以使得你的代碼更加簡潔高效。類似地,你也可以使用元組推導式。
字符串連接
當你需要創建一串字符串類似
0123456789
,你會如何做?
- Bad
string
=
''
for
i
in
range
(
10
)
:
string
+=
str
(
i
)
>>
>
string
'0123456789'
- Better
string
=
[
]
for
i
in
range
(
10
)
:
string
.
append
(
str
(
i
)
)
>>
>
''
.
join
(
string
)
'0123456789'
# or like this
string
=
[
str
(
i
)
for
i
in
range
(
10
)
]
>>
>
''
.
join
(
string
)
'0123456789'
- Best
string
=
map
(
str
,
range
(
10
)
)
>>
>
''
.
join
(
string
)
'0123456789'
join
是一種更加高效的字符串連接方式,使用 + 操作時,每執行一次 + 操作就會導致在內存中生成一個新的字符串對象,遍歷10次有10個字符串生成,造成無謂的內存浪費。而用
join
方法整個過程只會產生一個字符串對象。最后一個方法使用了
map
函數,在某些情況下,
map
函數更易于理解,效率更高。
"_"的妙用
在Python中,
_
的作用主要用來充當一個臨時變量,例如:
for
_
in
range
(
5
)
:
print
(
"Hello"
)
當你只需要一個循環多次重復做某件事,但是并不需要循環體的變量,就可以使用
_
當作一個占位符代替,同時也省去了命名的麻煩。
同時,在Python解釋器中,
_
還可以充當一個保存臨時結果的容器:
>>
>
1
+
2
3
>>
>
_
3
在這里
_
保存了上一次解釋器運行的結果。
同時,也可以作為多變量賦值的一個承載容器:
L
=
[
1
,
2
,
3
,
4
,
5
]
first
,
*
_
,
last
=
L
>>
>
fitst
1
>>
>
last
5
map函數
如果我們有一個函數,希望將其作用在一個list[0,1,2,3,4]上,如何實現?
- Bad
L
=
[
]
for
i
in
[
0
,
1
,
2
,
3
,
4
]
:
L
.
append
(
f
(
i
)
)
>>
>
L
[
0
,
1
,
4
,
9
,
16
]
- Better
>>
>
list
(
map
(
lambda
i
:
i
*
i
,
range
(
5
)
)
)
[
0
,
1
,
4
,
9
,
16
]
后者的代碼顯然一目了然。
map
接收兩個參數,一個是函數,一個是序列(迭代器),
map
將傳入的函數依次作用到序列(迭代器)的每個元素,并把結果作為新的迭代器返回。同時,作為Python內建的高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的
f ( x ) = x 2 f(x)=x^2
f
(
x
)
=
x
2
,還可以計算任意復雜的函數,例如作類型轉換:
>>
>
list
(
map
(
str
,
range
(
5
)
)
)
[
'0'
,
'1'
,
'2'
,
'3'
,
'4'
]
最后很重要的一點是,
map
可以接受多個迭代器序列,并且并行地對每個序列對應元素執行該函數,會比普通的函數更加高效。
reduce函數
如果我們需要將[1,2,3,4]轉化成1234,如何做?
- Bad
sum
=
0
for
i
in
[
1
,
2
,
3
,
4
]
:
sum
=
sum
*
10
+
i
>>
>
sum
1234
- Better
# reduce is not built-in function from python 3
from
functools
import
reduce
>>
>
reduce
(
lambda
x
,
y
:
x
*
10
+
y
,
[
1
,
2
,
3
,
4
]
)
1234
在Python 3中,
reduce
函數已經不再是內置函數,而是放入了functools模塊。
reduce
把一個函數作用在一個序列[x1, x2, x3…]上,這個函數必須接收兩個參數,
reduce
把結果繼續和序列的下一個元素做累積計算
filter函數
當你需要過濾一個列表的元素,例如,將列表中的奇數刪除,只留下偶數:
L
=
list
(
range
(
10
)
)
for
i
in
L
:
if
i
%
2
==
0
:
L
.
remove
(
i
)
>>
>
L
[
0
,
2
,
4
,
6
,
8
]
- Better
L
=
list
(
range
(
10
)
)
>>
>
list
(
filter
(
lambda
x
:
x
%
2
==
0
,
L
)
)
[
0
,
2
,
4
,
6
,
8
]
這里
filter
返回的是一個迭代器,顯然后者的方法比前者更加優雅簡潔。
生成器(generator)
前面介紹過,我們可以直接使用列表推導式創建一個完整的列表,當列表元素劇增的時候,如果只需要訪問某幾個元素,那將是十分浪費存儲空間的。而生成器正是為了解決這一問題,一邊循環一邊計算,列表元素按照某種算法推算出來,從而節省大量空間。
- Bad
>>
>
[
x
*
x
for
x
in
range
(
10
)
]
[
0
,
1
,
4
,
9
,
16
,
25
,
36
,
49
,
64
,
81
]
- Better
>>
>
(
x
*
x
for
x
in
range
(
10
)
)
<
generator
object
<
genexpr
>
at
0x000001EB028DBA98
>
二者的區別只是一個用了
[]
,另一個用了
()
,前者生成一個完整的列表,后者生成一個生成器。生成器的作用無疑是強大的,這里不作過多介紹,更多內容請參加Python文檔。
yield
寫一個簡單的斐波那契數列吧
- Bad
def
fib
(
n
)
:
x
,
y
=
0
,
1
L
=
[
]
for
i
in
range
(
n
)
:
L
.
append
(
y
)
x
,
y
=
y
,
x
+
y
return
L
>>
>
fib
(
5
)
[
1
,
1
,
2
,
3
,
5
]
- Better
def
fib
(
n
)
:
x
,
y
=
0
,
1
L
=
[
]
for
i
in
range
(
n
)
:
yield
y
x
,
y
=
y
,
x
+
y
>>
>
list
(
fib
(
5
)
)
[
1
,
1
,
2
,
3
,
5
]
后者使用了
yield
生成器,該生成器的特點是在哪里使用
yield
在哪里中斷,下次返回時候從中斷處開始執行,并且返回的是一個生成器,從而節省空間,提高代碼效率。關于
yield
的強大之處我這里不便詳細介紹,如果你需要詳細了解,請參見The Python yield keyword explained。
partial函數
函數在執行時,如果不是默認參數,就必須在調用前傳入。但是,有些參數是可以在函數被調用之前提前獲知的,這種情況下,一個函數有一個或多個參數預先就能知道,以便函數能用更少的參數進行調用。
我們先看一個乘法的例子,讓每個傳入的參數都乘以一個固定的常數:
# partial is not built-in function from python 3
from
functools
import
partial
def
mul
(
a
,
b
)
:
return
a
*
b
mul_partial
=
partial
(
mul
,
b
=
10
)
for
i
in
range
(
10
)
:
print
(
mul_partial
(
i
)
,
end
=
' '
)
# 0 10 20 30 40 50 60 70 80 90
也許你會說,這不就和默認參數一樣嗎,那我只要在定義函數
mul()
里將
b
固定為10,效果不是一樣的?
# using default parameters
def
mul
(
a
,
b
=
10
)
:
return
a
*
b
但是,如果你要傳入的
b
,你事先并不知道,而是需要在程序運行的時候才能獲取到,那么你如何提前使用固定參數確定好呢?這時候
partial
就有著極大的用處!
lru_cache
仍然是一個計算斐波那契數列的例子,這次我們使用遞歸實現(雖然遞歸效率遠低于循環,但這里只是作為一個例子演示,實際中最好少用遞歸)
- Bad
import
time
def
fib
(
n
)
:
if
n
==
0
:
return
0
if
n
==
1
:
return
1
return
fib
(
n
-
1
)
+
fib
(
n
-
2
)
start
=
time
.
time
(
)
>>
>
fib
(
40
)
102334155
>>
>
f
'Duration: {time.time() - start}s'
Duration
:
40.
126065492630005s
- Better
import
time
from
functools
import
lru_cache
@lru_cache
(
maxsize
=
512
)
def
fib
(
n
)
:
if
n
==
0
:
return
0
if
n
==
1
:
return
1
return
fib
(
n
-
1
)
+
fib
(
n
-
2
)
start
=
time
.
time
(
)
>>
>
fib
(
40
)
102334155
>>
>
f
'Duration: {time.time() - start}s'
Duration
:
0.
0009968280792236328s
可以看到,使用了LRU緩存后,二者的運行時間簡直天差地別。
枚舉
from
enum
import
Enum
,
auto
class
Animal
(
Enum
)
:
bird
=
auto
(
)
dog
=
auto
(
)
cat
=
auto
(
)
>>
>
print
(
Animal
.
cat
)
Animal
.
cat
Python 3 中的
Enum
類支持枚舉功能,可以使我們的程序變得更加簡潔。
Enum
是一種便捷的變量列表的打包方式,使用該方法能夠避免多個變量在代碼各處分布而顯得雜亂無章。枚舉是一個符號集合,每個符號都和唯一的變量對應。通過使用枚舉,我們可以通過符號標識來比較各個成員,我們還可以對枚舉本身進行迭代。
Reference
[1] Data, what now?
[2] The Hitchhiker’s Guide to Python
[3] The Python yield keyword explained
[4] Generators
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
