Python 列表 List

列表 List 讓 Python 的資料型態 Data Type 更有彈性。列表中的值稱為元素 element 或列表項 item。

列表的定義如下:

[ item1, item2, item3, ...]

列表中元素的 data type 可為任意項,甚至可以是嵌入 Nested 列表,例如:

['Apple', 85, ['Big', 'Small'], 4.0]

列表可被視為一個集合 Set。

1. 子集合相加

>>> A = [ 1, 2, 3 ]
>>> B = [ 4, 5, 6 ] 

>>> C = A + B
>>> C
[1, 2, 3, 4, 5, 6]

2. 次集合

>>> C[1:3]
[2, 3]

3. 變更元素

>>> C[0] = 99

>>> C

[99, 2, 3, 4, 5, 6]

 4. 遍歷列表

>>> for i in C:
...    print (i)
...
99
2
3
4
5
6

5. 刪除元素

>>> C.pop(1)
2
>>> C
[99, 3, 4, 5, 6]

6. 列表與字符串

字符串String是字符的序列,而列表List是值的序列。

>>> S = 'rice'
>>> T = list(S)
>>> T
['r', 'i', 'c', 'e']

 

>>> S = S + ' noodle'
>>> T = list(S)
>>> T
['r', 'i',

'c', 'e', ' ', 'n', 'o', 'o', 'd', 'l', 'e']

將字符拆成單個字母

>>> S
'rice noodle'
>>> T= S.split()
>>> T
['rice', 'noodle'] 

 

>>> S = 'rice, noodle'
>>> T = S.split(',')
>>> T
['rice', ' noodle']

這裡有個遺憾: 字串 S 中 rice 與 noodle 有個多餘的空格,當轉化為 List 後,逗號此分隔符 delimiter 沒有去掉多餘的空白。

>>> A = 'rice'
>>> B = 'rice'
>>> id(A)
37429464
>>> id(B)
37429464
>>> A is B
True

A 與 B 看是不同的對象 Object,但事實上 A 與 B 都是指標 Pointer,存放相同的值 37429464,這值指向位址為 37429464,而值為 'rice',所以 A 與 B 引用同一個對象。但,列表就不一樣:

>>> X = ['rice']
>>> Y = ['rice']
>>> id(X)
37364168
>>> id(Y)
34540488
>>> X is Y
False

列表 X 與 Y 是不同的對象,這 2 個列表有相同的元素,所以是相等的 Equivalent,但它們是不同的對象,所以不是相同的 Identical。

 但,若給 X 取個別名 Alias 為 Y 呢?

>>> Y = X
>>> id(X)
37364168
>>> id(Y)
37364168
>>> X is Y
True

這裡很清楚別名 Y 的位址指向與 X 相同,它們都指向同一個對象。

其次,區分修改列表的操作與新建列表的操作很重要。例如: append 方法修改列表,但, + 號操作新建立一個列別:

>>> Z = X.append('noodle')
>>> X
['rice', 'noodle']
>>> Z
>>> id(X)
37364168
>>> id(Z)
8791418547424
>>> Z
>>> X is Z
False

物件 X 引用函數 append,之後改變物件的存放值,並沒有因指定 Assign 給 Z,而新增一個物件 Z。


>>> X.append('bread')
>>> X
['rice', 'noodle', 'bread']
>>> id(X)
37364168

 以上就是明顯得例子。但,+ 號操作就不同, 例如:

>>> Y = X + ['soup']
>>> X
['rice', 'noodle', 'bread']
>>> Y
['rice', 'noodle', 'bread', 'soup']
>>> id(X)
37364168
>>> id(Y)
34571912

 運用 + 號操作,新增物件 Y,而這操作並不會改變原來物件 X 的值。

事實上 Python 也有 Call By Value (傳值) 與 Call By Address (傳址) 這概念。Call By Value 的操作不會改變原來物件 Object 的值,而 Call By Address 則會改變物件的值。這觀念相當重要

 >>> def replace(X,Y):
...    Z = X
...    X = Y
...    Y = Z
...    print(X,Y)
...
>>> X = 2
>>> Y = 3
>>> replace(X,Y)
3 2
>>> X
2
>>> Y
3

因為是 Call By Value,函數 replace(X,Y) 並沒有改變原來的 X 與 Y 值。

 >>> def replace_new(X,Y):
...     Z = X
...     X = Y
...     Y = Z
...     return X,Y

>>> X = 2
>>> Y = 3

>>> (X,Y) = replace_new(X,Y)
>>>
>>> X
3
>>> Y
2

Python 支援 Call By Reference 嗎? 依據參考[1] Python 不支援。

 

參考

1. Python: Call by Reference, https://stackoverflow.com/questions/47131458/python-call-by-reference

2. Facts and myths about Python names and values, https://nedbatchelder.com/text/names.html

/end

posted @ 2019-08-21 12:07  太川  阅读(130)  评论(0编辑  收藏  举报