2024-07-31|閱讀時間 ‧ 約 10 分鐘

Python 陣列 與 List comprehension 列表推導式

Array可以說是各種語言除了基本型別之外,最常用的資料型別與容器之一了。

Array 這種連續格子狀的資料結構,在Python要怎麼表達呢?


建立一個空的陣列

最簡單也最直接的寫法就是

array = [] # Python list [] 就對應到大家熟知的array 陣列型態的資料結構

或者

array = list() # 相當於呼叫list()的建構子

這兩個語法都相當於建立一個空的陣列。

印出來,可以很清楚看到結果,就是一個[],裡面什麼東西都沒有。


增加元素

在尾巴加入新元素

array.append( x ) # 在尾巴插入一個新的元素。

用起來就好像C++ vector 的 push_back(x) ,會在尾端新增一筆資料,內容為x


在指定位置插入新元素

# 在pos位置,插入element
# pos 從0開始起算,0是最前面的位置
array.insert(pos, element)

觀念上有點像C++ vector的insert,差別在於C++接收的參數是iterator

除非有特殊需求,一般日常應用不建議這麼用,因為複雜度是O(n)線性等級的。

run-time的時間成本很高。


讀取指定陣列位址的元素

和其他主流高階語言相同,都支援array[index]的陣列元素存取語法。

index 同樣是從0開始起算,0是開頭的索引編號

# 印出array[0]
print( array[0])

index = 1
# 印出array[index]​
print( array[index])

刪除元素

刪除並且回傳尾巴最後一個元素

array.pop()

如果把array 當成stack來用,

那麼array.append(x) 就對應到 stack 的 push(x) 操作

array.pop() 就對應到 stack 的 pop()操作


刪除並且回傳指定位置的陣列元素

# 刪除並且回傳array[pos]
# pos 從0開始起算,0是最前面的位置
array.pop( pos )

觀念上有點像C++ vector的erase,差別在於C++接收的參數是iterator

除非有特殊需求,一般日常應用不建議這麼用,因為複雜度是O(n)線性等級的。

run-time的時間成本很高。


建立帶有初始值的陣列

如何有規律的生成元素,或者生成一整塊帶有初始值的陣列?

傳統高階語言寫法: 使用迴圈

如果我們要建立一個長度為10的陣列,裡面初始值都是0。

可以這樣寫

array = []

for i in range(10):
array.append(0)

print(array)

得到的輸出就是

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


另一個例子是,如果建立一個長度為10的陣列,裡面初始值就是流水號0~9。

可以這樣寫

array = []

for i in range(10):
array.append(i)

print(array)

得到的輸出就是

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

List comprehension 列表推導式

Python提供一個更簡潔也更彈性的語法List comprehension,
中文稱之為列表推導式(或 列表生程式),
可以在把初始化的常數、運算式或函式直接放在[]裡面。

語法可以這樣表達

[ 初始值 for 索引變數 in range( ... ) ]

或者

[ 函式計算的結果 for 索引變數 in range( ... ) ]


如果我們要建立一個長度為10的陣列,裡面初始值都是0。

用List comprehension來寫,就變成這樣

array =[ 0 for i in range(10)]
print(array)

得到的輸出同樣是

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


如果我們要建立一個長度為10的陣列,裡面初始值是流水號0~9。

用List comprehension來寫,就變成這樣

array =[ i for i in range(10)]
print(array)

得到的輸出就是

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


如同剛剛語法的介紹,給予函數計算結果或者等價的lambda expression 也是可以的。

例如,想要根據奇數、偶數輸出提示字串,可以這樣寫

def judge(x):
if x % 2 == 0:
return f"{x} is Even"
else:
return f"{x} is Odd"

array =[ judge(i) for i in range(6) ]
print(array)

得到的輸出就是

['0 is Even', '1 is Odd', '2 is Even', '3 is Odd', '4 is Even', '5 is Odd']


例如,想要得到前10個完全平方數,可以這樣寫

array =[ i**2 for i in range(1, 11, 1) ]
print(array)

得到的輸出就是

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


例如,想要判斷流水號i 是不是3的倍數,可以這樣寫

array =[ (i % 3 ==0) for i in range(6) ]
print(array)

得到的輸出就是

[True, False, False, True, False, False]


另外,由於支援range迭代器(起點, 終點, 步伐)的語法,

所以控制起點、終點迭代區間也是可行的。


註: Python range的區間是包含起點,不包含終點,請特別留意


例如,想要輸出100到120之間的偶數陣列,可以這樣寫

array =[ i for i in range(100, 122, 2) ]
print(array)

得到的輸出就是

[100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120]

Reference:

[1] 5. Data Structures — Python 3.12.4 documentation

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.