iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
自我挑戰組

Python 學習整理系列 第 23

Day23. List v.s. Turple

  • 分享至 

  • xImage
  •  

List(列表)是什麼?

  • list 表示方式為 方括號[]
  • list 可將多個項目儲存在單一變數中
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 是有順序的,如果有新增項目到列表中,新項目會被放置在列表的尾端
  • list 是可以改變的,可更改、新增和刪除列表中的項目
  • list 元素的位置 (index),第一個位置為 [ 0 ] ,第二個位置為 [ 1 ]

以這程式碼為例子,若我想返回值取得 34 這項元素

list = [-4, 34, True, 5.5, "male", [5, 5], (5, 6), {6, 7}]

print(list[1])

其值為:34


Turple 固定列表

  • Turple 表示方式為小括號()
  • Tuple 可將多個項目儲存在單一變數中
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})


Tuple 是有順序且不可更改的集合,所以不可以用 append()、remove()、pop()

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'


如果 Tuple 裡面只有一個值,那括號裡面的值後面要加一個逗號,不然 Python會誤認型態。

a = (5)

print(type(a))

其值為:<class 'int'>


若在後面加一個逗號

a = (5,)

print(type(a))

其值為:<class 'tuple'>


番外篇: [] 與 list(),哪一個更快? 為什麼它會更快?

  1. [ ] 與 list( ),哪一個更快?
    使用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() 哪个快?为什么快?快多少呢?


上一篇
Day22. is v.s ==
下一篇
Day24. 什麼是 monkey patching?
系列文
Python 學習整理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言