方括號[]
list = [-4, 34, True, 5.5, "male", [5, 5], (5, 6), {6, 7}]
print(list)
其值為:[-4, 34, True, 5.5, 'male', [5, 5], (5, 6), {6, 7}]
list = [-4, 34, True, 5.5, "male", [5, 5], (5, 6), {6, 7}]
print(list[1])
其值為:34
小括號()
list = (-4, 34, True, 5.5, "male", [5, 5], (5, 6), {6, 7})
print(list)
其值為:(-4, 34, True, 5.5, 'male', [5, 5], (5, 6), {6, 7})
list = (-4, 34, True, 5.5, "male", [5, 5], (5, 6), {6, 7})
list.append(-1)
print(list)
其值為:AttributeError: 'tuple' object has no attribute 'append'
a = (5)
print(type(a))
其值為:<class 'int'>
若在後面加一個逗號
a = (5,)
print(type(a))
其值為:<class 'tuple'>
timeit
模組的timeit()函式就能測試[] 的測試速度
import timeit
print(timeit.timeit('[]', number=10**7))
其值為:0.13636989996302873
list()的測試速度
import timeit
print(timeit.timeit('list()', number=10**7))
其值為:0.2976907999254763
如上述程式碼所述,在各自呼叫1000萬次的情況下,[ ] 建立方式只花費了0.13秒,而list ( ) 建立花費0.29秒,後者的耗時是前者的2.23倍!
2.為什麼它會更快?
這一次我們可以使用 dis
模組的 dis()
函式,看看兩者執行的位元組碼有何差別:
from dis import dis
print(dis("[]"))
其值為:0 BUILD_LIST
2 RETURN_VALUE
from dis import dis
print(dis("()"))
其值為:0 LOAD_CONST
2 CALL_FUNCTION
4 RETURN_VALUE
如上述程式碼所示,[] 的位元組碼有兩條指令(BUILD_LIST 與 RETURN_VALUE),而 ()的位元組碼有三條指令(LOAD_CONST、CALL_FUNCTION與RETURN_VALUE)。
首先,對於 [ ],它是 Python 中的一組字面常數(literal),像數字之類的字面常數一樣,表示確切的固定值。也就是說,Python 在解析到它時,就知道它要表示一個列表,因此會直接呼叫編譯器中構建列表的方法(對應 BUILD_LIST ),來建立列表,所以是一步到位。
而對於 list(),“list”只是一個普通的名稱,並不是字面量,也就是說編譯器一開始並不認識它。
因此,編譯器的第一步是要找到這個名稱(對應 LOAD_NAME)。它會按照一定的順序,在各個變數中逐一查詢(區域變數--全域變數--內建變數),直到找到為止,找不到則會丟擲NameError
。
編譯器看到“list”之後是一對圓括號,因此第二步是把這個名稱當作可呼叫物件來呼叫,即把它當成一個函式進行呼叫(對應 CALL_FUNCTION)。
因此,list() 在建立列表時,需要經過名稱查詢與函式呼叫兩個步驟,才能真正開始建立列表(注:CALL_FUNCTION 在底層還會有一些函式呼叫過程,才能走到跟 BUILD_LIST 相通的邏輯,此處我們忽略不計)。
至此,我們就可以回答前面的問題了:因為 list() 涉及的執行步驟更多,因此它比 [] 要慢一些
。
參考資料:
w3schools - Python Lists
w3schools - Python Tuples
Python 有序列表的基本運算 - List、Tuple By 彭彭
資料型態與轉換. Python 內建資料形態的介紹與應用 | by 陳子晴
Python有了串列(list),為何還要有元組(tuple) ?
3-2 Tuple Courseea -用 Python 做商管設計(二)
Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?