5. 資料結構 - 串列, Tuple


資料結構定義

前面介紹了基本的型別, 但實際上的使用, 我們可能會有很多的物件, 例如我們可能要存放 1 到 5 的值

>>> num1 = 1
>>> num2 = 2
>>> num3 = 3
>>> num4 = 4
>>> num5 = 5

但是這樣的方式太繁雜又容易出錯, 所以有了資料結構(Data structure)的概念


List 與 Tuple

電腦中把一連串的有序資料存放起來, 我們稱為序列

基本上關於序列的資料結構我們已經在前面看過了, 其實字串就是一個只存放字元的資料結構

python 提供了串列(List)Tuple兩種表示一序列的資料結構, 裡面可以存放任何的物件序列

而這兩種表示序列的資料結構有什麼不同?

list是可變的, 代表宣告了之後可以任意的從中取走某個物件或插入物件

tuple是不可變的, 宣告物件給他之後, 就無法再做更改了

其實大部分的時間都是使用 list, 但是在一個良好的程式架構中, 我們應該要盡量用 tuple 取代 list

  1. tuple 佔用的記憶體空間比較小

  2. tuple 不能被修改, 對初學者來說可能覺得這是缺點, 為什麼要使用? 但是在程式架構中, 我們會有一些序列是不能夠被更動的, 所以當我們將它宣告為 tuple 後, 就能避免這件事發生

  3. 函式的引數是以 tuple 傳入的


Tuple

Tuple跟costco一樣, 有人唸 costco, 另外有的人念 costco

Tuple有的人念 too-pull, 有的人念 tub-pull, 其實 python 作者是說都可以, 所以不要在意他念什麼

當我們今天要定義一個空的 tuple 時, 我們會給他一個 () , 而裡面為空來表示

>>> emptyTuple = ()
>>> emptyTuple
()

所以我們可能會以為用 () 裡面放物件以後就是定義 tuple

>>> someTuple = ('stringA', 'stringB', 'stringC')
>>> someTuple
('stringA', 'stringB', 'stringC')

實際上, , 才是他的本體, 我們也可以這樣去宣告

>>> someTuple = 'stringA', 'stringB', 'stringC'
>>> someTuple
('stringA', 'stringB', 'stringC')

>>> oneTuple = 'string',
>>> oneTuple
('string',)

>>> tupleA = ('string',)
>>> tupleA
('string',)

>>> a_str = ('string')
>>> a_str
'string'

最後一個例子, 沒有加上,, 只有 () 是不會被當作 tuple

但習慣以及可讀性上, 我們通常還是會加上()

從位置取回值

我們將物件指派給了一個序列, 序列會為這些物件照順序給予編號, 也就是在序列中的位置(index)

這時候, 取值的方式就跟字串很像了

>>> t = ('a', 'b', 'c', 'd')
>>> t[0]
'a'

一樣使用[]並輸入index來取回該位置的值, list 也是一樣的

指派多個變數

python 相較於大部分語言有另一個特性就是可以同時指派多個變數, 請看範例

>>> a, b, c = 1, 2, 3
>>> a
1
>>> b
2
>>> c
3

>>> (a, b, c) = (1, 2, 3)
>>> a
1
>>> b
2
>>> c
3

其實就是tuple的一個特性, 所以我們可以這樣寫

>>> testTuple = (1, 2, 3)
>>> a, b, c = testTuple
>>> a
1
>>> b
2
>>> c
3

這種行為我們稱為tuple 開箱(unpacking)

基於這個特性, 使得 python 在交換值得時候能非常方便

>>> num1 = 15
>>> num2 = 20
>>> num1, num2 = num2, num1
>>> num1
20
>>> num2
15

這件事在大部分的程式語言可是一個經典的問題


list

我們可以用兩種方式來宣告一個空的list

>>> emptyList = []
>>> emptyList
[]

>>> emptyList2 = list()
>>> emptyList2
[]

上面有提到list()這個函式, 其實跟之前提到過的str()類似, 就是將()內的東西轉型成list

>>> list('string')
['s', 't', 'r', 'i', 'n', 'g']

>>> list('aaa')
['a', 'a', 'a']

>>> aTuple = (1, 2, 3)
>>> list(aTuple)
[1, 2, 3]

另外在常用的字串應用時提到的

>>> "ab,cd,ef".spilt(',')
['ab', 'cd', 'ef']

spilt()所回應的結果也是list

利用index更改該內容

前面提到了[]的用法, 因為list的特性, 使得我們可以透過index對值做修改

>>> aList = [1, 2, 3]
>>> aList
[1, 2, 3]

>>> aList[1] = 5
>>> aList
[1, 5 ,3]

>>> aList[1] = 'string'
>>> aList
[1, 'string', 3]

字串就沒辦法這麼做, 因為他是一種不可修改的序列

取一個範圍的list

同樣的, 他跟字串的[]有類似的用法, 我們直接看範例

>>> aList = ['aa', 'bb', 'cc', 'dd', 'ee']
>>> aList[1:3]
['bb', 'cc', 'dd']
>>> aList[::2]
['aa', 'cc', 'ee']

從結尾的地方新增項目

假設我們想要加入一個新的項目, list提供了append()

>>> aList = ['aa', 'bb', 'cc']
>>> aList.append('dd')
>>> aList
['aa', 'bb', 'cc', 'dd']

但是如果今天是一個 list 要再接另一個 list 要怎麼做, python 也有提供一街快速的方法

使用extend()函式

>>> listOne = ['a', 'b']
>>> listTwo = ['c', 'd']
listOne.extend(listTwo)
>>> listOne
['a', 'b', 'c', 'd']

其實在之前我們有提到一個 += 的運算, 在這裡可以直接代替extend使用

>>> listOne = ['a', 'b']
>>> listOne += ['c', 'd']
>>> listOne
['a', 'b', 'c', 'd']

到這裡我們就要順便提一下字串串接了

前面提到過用+來串接字串, 不過在這裡其實也可以用 += 來串接

>>> a_str = "abc"
>>> a_str += "def"
>>> a_str
'abcdef'

其實就是同等於a_str = a_str + "def"

新增與刪除

關於list的新增, 這裡我們直接先看範例

>>> aList = ['a', 'b', 'c']
>>> aList.insert(1, 'eee')
>>> aList
['a', 'eee', 'b', 'c']

insert的第一個引數代表要新增的位置, 第二個代表要放入的物件

>>> aList = ['a', 'b', 'c']
>>> del aList[1]
>>> aList
['a', 'c']

del比較特別, 他不是函式, 而是類似於=這種陳述, 他剛好跟=指派的動作相反, 他會將物件與名稱分離

通常我們還會使用remove函式來做刪除

>>> aList = ['a', 'b', 'c']
>>> aList.remove('b')
>>> aList
['a', 'c']

還有一個方式,pop能夠更快速靈活的使用, 並且將刪除的值取出來

>>> aList = ['a', 'b', 'c', 'd']
>>> aList.pop()
'd'
>>> aList
['a', 'b', 'c']

>>> aList.pop(1)
'b'
>>> aList
['a', 'c']

類似於pop這種函式, 他讓我們自己決定要不要帶引數, pop假設不帶引數就是直接移除最後一個

項目是否存在

python 提供了一個方便的運算符號來讓我們知道某個值在不在資料結構中, 我們使用'in'

>>> aList = ['a', 'b', 'c']
>>> 'a' in aList
True
>>> 'd' in aList
False

當我們使用in, 程式會回應一個布林值跟我們說有沒有辦法找到這個值

不過有時候我們不只要找到他, 還要知道他在哪一個index, 很直覺的, 我們就使用index函式

>>> aList = ['a', 'b', 'c']
>>> aList.index('b')
1

>>> aList.index('d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'd' is not in list

這裡忽然出現很奇怪的內容, 我們稱為例外(execption),

我們嘗試要從aList取找'd', 但是其實裡面沒有這個東西, 這個函式就會沒辦法處理

通常我們軟體會崩潰(crash)也是因為出現例外, 沒有處理好

所以使用index前我們還是要確保他是否存在

複製list

我們之前提到過, =是指派, 而非直接複製

>>> aList = [1, 2, 3]
>>> bList = aList
>>> aList
[1, 2, 3]
>>> bList
[1, 2, 3]

>>> aList[0] = 'aa'
>>> aList
['aa', 2, 3]
>>> bList
['aa', 2, 3]

如同之前提到, =只是將物件指派給他一個變數名稱,

[1, 2, 3]這個list型態的物件被改動的時候, aListbList 這兩個變數同時都是被指派[1, 2, 3]這個物件

才會有一樣的結果

如果要複製, 我們可以使用copy函式

>>> aList = [1, 2, 3]
>>> bList = aList.copy()

或是使用list函式

>>> aList = [1, 2, 3]6
>>> bList = list(aList)

還可以直接這樣使用

>>> aList = [1, 2, 3]
>>> bList = aList[:]

bList = aListbList = aList[:] 是不一樣的,

[]是用來取出某個位置的物件並把它獨立出來, 所以這裡也可以直接全部取出來當作複製的功用

其他應用

其他包含了len, count等等就不在多做介紹, 可以很簡單的找到這些用法跟範例

results matching ""

    No results matching ""