堅持原創輸出,點選藍字關注我吧
作者:清菡
部落格:oschina、雲+社群、知乎等各大平臺都有。
目錄
- 一、元組和列表
- 1.元組和列表的效能分析
- 2.為什麼列表在 Python 中是最常用的呢?
- 3.timeit 裡面有個 Timer 類
- 4.timeit 裡面還有個直接用的 timeit 的方法,timeit.timeit()
- 5.這 2 個方法有啥區別?
- 二、命名元組
- 三、命名元組有什麼特點?
一、元組和列表
1.元組和列表的效能分析
元組和列表用來儲存資料,在元組和列表裡面查詢的時候,到底哪個更快呢?
計算建立元組和列表所需的時間:ipython 中使用timeit
這個命令。
計算時間模組介紹:
import timeit
#timeit.timeit
可以用這個模組來測試函式的效能。
安裝 ipython:pip install ipython
ipython 是個互動環境,就跟我們輸入 Python 進去是一樣的。只不過它外面做了一層封裝,比 Python 互動環境更好用一點。
ipython 裡面有一個命令叫做timeit
,後面可以跟一個 Python 表示式。
例如定義一個列表在後面:
敲完這行命令,返回了一行時間。這個是在記憶體中初始化一個列表,如圖可以看到建立了一千萬次,時間是 48.4ns
可以看出,建立一個元組比建立一個列表要快得多。
元組的速度比列表要快 3 倍多。在記憶體裡,當我們建立一個列表的時候,會劃分一塊區域出來,拿一塊區域給列表來儲存值。例如初始化,裡面給它留了 20 個位置在這個列表裡面儲存值。
當儲存到一定程度,Python 直譯器檢測到列表快要盛滿了的時候,它會對列表做一個擴容。
給擴容到 200,當儲存到 150 的時候,發現又快儲存滿了,又會給你繼續擴容。
隨著資料的增多,底層會不斷給這個列表擴容。
初始化一個元組,同樣也是一千萬次,只需 12.8ns
元組是一個不可變的型別。
比如定義的元組裡面有 3 個元素,Python 直譯器在給它分記憶體的時候,就給它分了 3 個格子。
這裡面只能存 3 條資料,就這麼大,所以元組佔用的記憶體比列表要少。
用一個列表儲存 50 條資料和用一個元組儲存 50 條資料,那麼元組佔用的記憶體要比列表小得多。
2.為什麼列表在 Python 中是最常用的呢?
因為列表比較靈活,用列表的話,可以往裡面不斷得新增元素。如果元素固定的,那就用元組。
3.timeit 裡面有個 Timer 類。
來看看這個類的原始碼:
timer=default_timer
代表的是:建立一個列表、元組等,它要執行的一個次數。
看原始碼,預設是一千萬次:
import timeit # 這個模組可以用來做效能分析
def func():
for i in range(10):
print(i)
# 這個物件有個方法叫做timeit
res = timeit.Timer(func).timeit(100) # 把這個func函式傳進去,執行100次,然後返回的是個時間
# timeit.Timer(func).timeit(100)中函式func是不需要加引號的,如果是字串、列表這些需要加
# 引號放進去
print(res)
可以看到執行 100 次需要的時間是:0.0043269999999999975
4.timeit 裡面還有個直接用的 timeit 的方法,timeit.timeit()
import timeit # 這個模組可以用來做效能分析
def func():
for i in range(10):
print(i)
# 這個物件有個方法叫做timeit
# res = timeit.Timer(func).timeit(100) # 把這個func函式傳進去,執行100次,然後返回的是個時間
# timeit.Timer(func).timeit(100)中函式func是不需要加引號的,如果是字串、列表這些需要加引號放進去
# print(res)
res2 = timeit.timeit('[1,2,3]')
print(res2)
這個模組的作用: 大家寫的功能函式,可以用它測下功能函式的速度,執行大概要多久。
預設是一千萬次,結果如下:
如果列表不加引號直接傳是會報錯的:
提示不可被呼叫!
5.這 2 個方法有啥區別?
其實它們是一個東西。
二、命名元組
元組的效能是大大優於列表的。元組、列表在使用的時候,都是通過下標索引取值的。
下標索引取值不太人性化,如果我知道資料儲存在元組裡面,但是我不知道它具體儲存的下標位置。這個時候找這個元素,還得先把下標找出來,知道下標再去拿,這樣很不方便。
字典的話,這方面就比較有優勢。資料是儲存在字典裡面的,只要通過鍵,就能把值找到。字典相對於元組和列表,有一定的優勢和劣勢。
命名元組使用的時候可以讓元組像字典一樣去取值。
例如,有個元組裡面儲存了 3 條資料:
建立一個命名元組的話,需要用到 Python 的一個內建模組from collections import namedtuple
import timeit # 這個模組可以用來做效能分析
from collections import namedtuple
# namedtuple是個函式,建立命名元組可以通過這個函式來建立
def func():
for i in range(10):
print(i)
# 這個物件有個方法叫做timeit
# res = timeit.Timer(func).timeit(100) # 把這個func函式傳進去,執行100次,然後返回的是個時間
# timeit.Timer(func).timeit(100)中函式func是不需要加引號的,如果是字串、列表這些需要加引號放進去
# print(res)
res2 = timeit.timeit('[1,2,3]')
print(res2)
# 命名元組
# 如果知道里面儲存的具體位置,可以通過下標取值。例如tu=[0]
# 如果我不知道名字儲存在哪裡,通過下標去取值就不好取了
# 命名元組可以使取值的時候像列表一樣取
student_info = namedtuple('info_tuple',['name','age','gender']) # 這個函式接收2個引數,第一個引數是建立命名元組的型別的名字;
# 第二個引數的話,傳一個列表
# 列表裡寫建立命名元組的一個命名,例如第一個元素命名為name
# 這個函式呼叫傳了2個引數,返回出來一個物件。這個物件叫做student_info
# 通過這個物件student_info建立命名元組
tu = student_info('qinghan',18,'nv')
print(tu)
這個 tu 就是個命名元組。
student_info
是通過命名元組這個namedtuple
函式建立命名元組型別:namedtuple('info_tuple',['name','age','gender'])
。
然後返回出來一個物件student_info
通過student_info
這個物件傳入對應的元組,定義元組的時候就通過這個物件把元素寫進去,返回的就是命名元組。
三、命名元組有什麼特點?
它取值的時候可以像字典一樣取值,通過對應的鍵,找到對應的值。命名元組使用起來更像物件。
這樣用:命名元組.name
這樣就能找到 name 所對應的值:
import timeit # 這個模組可以用來做效能分析
from collections import namedtuple
# namedtuple是個函式,建立命名元組可以通過這個函式來建立
def func():
for i in range(10):
print(i)
# 這個物件有個方法叫做timeit
# res = timeit.Timer(func).timeit(100) # 把這個func函式傳進去,執行100次,然後返回的是個時間
# timeit.Timer(func).timeit(100)中函式func是不需要加引號的,如果是字串、列表這些需要加引號放進去
# print(res)
res2 = timeit.timeit('[1,2,3]')
print(res2)
# 命名元組
# 如果知道里面儲存的具體位置,可以通過下標取值。例如tu=[0]
# 如果我不知道名字儲存在哪裡,通過下標去取值就不好取了
# 命名元組可以使取值的時候像列表一樣取
student_info = namedtuple('info_tuple',['name','age','gender']) # 這個函式接收2個引數,第一個引數是建立命名元組的型別的名字;
# 第二個引數的話,傳一個列表
# 列表裡寫建立命名元組的一個命名,例如第一個元素命名為name
# 這個函式呼叫傳了2個引數,返回出來一個物件。這個物件叫做student_info
# 通過這個物件student_info建立命名元組
tu = student_info('qinghan',18,'nv')
print(tu.name)
設定命名元組型別的時候,它返回的這個物件它裡面只包含了傳進去的這幾個名字。
接下來,要建立命名元組的時候,元素和它一樣多,名字和對應的元素的值是一一對應的,不能多,不能少。
否則就會報錯:
print(type(tu)) # 看下它的型別
它返回的物件和型別名用的同一個名字。
print(type(student_info))
import timeit # 這個模組可以用來做效能分析
from collections import namedtuple
# namedtuple是個函式,建立命名元組可以通過這個函式來建立
def func():
for i in range(10):
print(i)
# 這個物件有個方法叫做timeit
# res = timeit.Timer(func).timeit(100) # 把這個func函式傳進去,執行100次,然後返回的是個時間
# timeit.Timer(func).timeit(100)中函式func是不需要加引號的,如果是字串、列表這些需要加引號放進去
# print(res)
res2 = timeit.timeit('[1,2,3]')
print(res2)
# 命名元組
# 如果知道里面儲存的具體位置,可以通過下標取值。例如tu=[0]
# 如果我不知道名字儲存在哪裡,通過下標去取值就不好取了
# 命名元組可以使取值的時候像列表一樣取
# 設定命名元組型別
# student_info是個類
student_info = namedtuple('student_info',['name','age','gender']) # 這個函式接收2個引數,第一個引數是建立命名元組的型別的名字;
# 第二個引數的話,傳一個列表
# 列表裡寫建立命名元組的一個命名,例如第一個元素命名為name
# 這個函式呼叫傳了2個引數,返回出來一個物件。這個物件叫做student_info
# 通過這個物件student_info建立命名元組
tu = student_info('qinghan',18,'nv')
print(tu.name)
print(type(tu)) # 看下它的型別
print(type(student_info))
# 因為student_info是個類,所以看student_info的type就是個type。隨便看哪個類都是一樣的。
公眾號 「清菡軟體測試」 首發,更多原創文章:清菡軟體測試 105+原創文章,歡迎關注、交流,禁止第三方擅自轉載。