跳轉到內容

Python 程式設計/序列

來自 Wikibooks,開放世界中的開放書籍


序列允許您以一種組織且高效的方式儲存多個值。共有七種序列型別:字串、位元組、列表、元組、位元組陣列、緩衝區和範圍物件。字典和集合是用於儲存順序資料的容器。

我們已經介紹過字串,但那是在您不知道什麼是序列之前。在其他語言中,陣列中的元素以及有時字串中的字元可以使用方括號或下標運算子進行訪問。這在 Python 中也適用。

>>> "Hello, world!"[0]
'H'
>>> "Hello, world!"[1]
'e'
>>> "Hello, world!"[2]
'l'
>>> "Hello, world!"[3]
'l'
>>> "Hello, world!"[4]
'o'

索引從 0 到 n-1 編號,其中 n 是專案(或字元)的數量,它們從字串的開頭開始賦予字元。

 H  e  l  l  o  ,     w  o  r  l  d  !
 0  1  2  3  4  5  6  7  8  9 10 11 12

負索引(從 -1 到 -n 編號)從字串的末尾開始計數。

 H   e   l   l   o   ,       w   o   r  l  d  !
-13 -12 -11 -10 -9  -8  -7  -6  -5  -4 -3 -2 -1
>>> "Hello, world!"[-2]
'd'
>>> "Hello, world!"[-9]
'o'
>>> "Hello, world!"[-13]
'H'
>>> "Hello, world!"[-1]
'!'

如果括號中給出的數字小於 -n 或大於 n-1,則我們會得到一個 IndexError 錯誤。

但在 Python 中,冒號 : 允許方括號取兩個數字。對於任何僅使用數字索引的序列,這將返回指定索引之間的部分。這稱為“切片”,切片字串的結果通常稱為“子字串”。

>>> "Hello, world!"[3:9]
'lo, wo'
>>> string = "Hello, world!"
>>> string[:5]
'Hello'
>>> string[-6:-1]
'world'
>>> string[-9:]
'o, world!'
>>> string[:-8]
'Hello'
>>> string[:]
'Hello, world!'

如上所示,如果省略第一個和第二個數字,則它們將取其預設值,分別為 0 和 n-1,分別對應於序列的開頭和結尾(在本例中)。還要注意,括號在左側是包含的,但在右側是排除的:在上面第一個例子 [3:9] 中,索引 3 處的字元 'l' 包含在內,而索引 9 處的字元 'r' 被排除在外。

我們可以在括號中新增第三個數字,透過在括號中新增一個冒號,這表示切片的增量步長

>>> s = "Hello, world!"
>>> s[3:9:2] #returns the substring s[3]s[5]s[7]
'l,w'
>>> s[3:6:3] #returns the substring s[3]
'l'
>>> s[:5:2] #returns the substring s[0]s[2]s[4]
'Hlo'
>>> s[::-1] #returns the reverted string
'!dlrow ,olleH'
>>> s[::-2] #returns the substring s[-1]s[-3]s[-5]s[-7]s[-9]s[-11]s[-13]
'!lo olH'

增量步長可以是正數或負數。對於正增量步長,切片是從左到右的,對於負增量步長,切片是從右到左的。此外,我們應該意識到

  • 增量步長的預設值為 1
  • 當增量步長為負時,第一個和第二個數字的預設值分別變為 -1(或 n)和 -n(或 0)(當增量步長為正時,與上面的預設值相同)
  • 增量步長不能為 0

列表正如其名:一個按順序組織的值列表。列表使用方括號建立。例如,空列表將這樣初始化

spam = []

列表的值用逗號分隔。例如

spam = ["bacon", "eggs", 42]

列表可以包含不同型別的物件。它可以同時儲存字串“eggs”和“bacon”,以及數字 42。

與字串中的字元類似,列表中的專案可以透過從 0 開始的索引進行訪問。要訪問列表中的特定專案,您可以透過列表的名稱,後跟括號內列表中專案的編號來引用它。例如

>>> spam
['bacon', 'eggs', 42]
>>> spam[0]
'bacon'
>>> spam[1]
'eggs'
>>> spam[2]
42

您也可以使用負數,它從列表的末尾向後計數。

>>> spam[-1]
42
>>> spam[-2]
'eggs'
>>> spam[-3]
'bacon'

len() 函式也適用於列表,返回陣列中的專案數量。

>>> len(spam)
3

請注意,len() 函式計算列表內部專案的數量,因此 spam 中的最後一個專案(42)具有索引 (len(spam) - 1)。

列表中的專案也可以更改,就像普通變數的內容一樣。

>>> spam = ["bacon", "eggs", 42]
>>> spam
['bacon', 'eggs', 42]
>>> spam[1]
'eggs'
>>> spam[1] = "ketchup"
>>> spam
['bacon', 'ketchup', 42]

(字串由於不可變,因此無法修改。)與字串一樣,列表也可以被切片。

>>> spam[1:]
['eggs', 42]
>>> spam[:-1]
['bacon', 'eggs']

也可以向列表中新增專案。有許多方法可以做到這一點,最簡單的方法是使用列表的 append() 方法。

>>> spam.append(10)
>>> spam
['bacon', 'eggs', 42, 10]

請注意,您不能透過指定超出其範圍的索引來手動插入元素。以下程式碼將失敗。

>>> spam[4] = 10
IndexError: list assignment index out of range

相反,您必須使用 insert() 函式。如果要在列表中的某個索引處插入一個專案,可以使用列表的 insert() 方法,例如

>>> spam.insert(1, 'and')
>>> spam
['bacon', 'and', 'eggs', 42, 10]


您還可以使用 del 語句從列表中刪除專案。

>>> spam
['bacon', 'and', 'eggs', 42, 10]
>>> del spam[1]
>>> spam
['bacon', 'eggs', 42, 10]
>>> spam[0]
'bacon'
>>> spam[1]
'eggs'
>>> spam[2]
42
>>> spam[3]
10

如您所見,列表會重新排序自身,因此編號中沒有間隙。

列表有一個不尋常的特性。給定兩個列表 a 和 b,如果您將 b 設定為 a,並更改 a,b 也會被更改。

>>> a=[2, 3, 4, 5]
>>> b=a
>>> del a[3]
>>> print(a)
[2, 3, 4]
>>> print(b)
[2, 3, 4]

這可以透過使用 b=a[:] 來輕鬆解決。

有關列表的更多說明,或瞭解如何建立二維陣列,請參閱 資料結構/列表

元組類似於列表,但它們是不可變的。一旦設定了元組,就無法以任何方式更改它:您無法新增、更改或刪除元組的元素。否則,元組的工作方式與列表相同。

要宣告元組,您使用逗號。

unchanging = "rocks", 0, "the universe"

通常需要使用括號來區分不同的元組,例如在同一行上進行多個賦值時。

foo, bar = "rocks", 0, "the universe" # 3 elements here fail - too many values
foo, bar = "rocks", (0, "the universe") # 2 elements here because the second element is a tuple

可以使用不必要的括號,不會造成損害,但巢狀括號表示巢狀元組。

>>> var = "me", "you", "us", "them"
>>> var = ("me", "you", "us", "them")

兩者都生成

>>> print(var)
('me', 'you', 'us', 'them')

>>> var = ("me", "you", ("us", "them"))
>>> print(var)
('me', 'you', ('us', 'them')) # A tuple of 3 elements, the last of which is itself a tuple.

有關元組的更多說明,請參閱 資料結構/元組

字典也類似於列表,並且它們是可變的——您可以新增、更改和刪除字典中的元素。但是,字典中的元素不像列表那樣繫結到數字。字典中的每個元素都有兩個部分:鍵和值。呼叫字典的鍵將返回與該鍵關聯的值。您可以將列表視為一種特殊的字典,其中每個元素的鍵都是一個按數字順序排列的數字。

字典使用花括號宣告,每個元素首先由其鍵宣告,然後是一個冒號,然後是其值。例如

>>> definitions = {"guava": "a tropical fruit", "python": "a programming language", "the answer": 42}
>>> definitions
{'python': 'a programming language', 'the answer': 42, 'guava': 'a tropical fruit'}
>>> definitions["the answer"]
42
>>> definitions["guava"]
'a tropical fruit'
>>> len(definitions)    
3

此外,向字典中新增元素要簡單得多:只需像宣告變數一樣宣告它即可。

>>> definitions["new key"] = "new value"
>>> definitions
{'python': 'a programming language', 'the answer': 42, 'guava': 'a tropical fruit', 'new key': 'new value'}

有關字典的更多說明,請參閱 資料結構/字典

集合就像列表一樣,除了它們是無序的並且不允許重複值。集合的元素既不繫結到數字(如列表和元組),也不繫結到鍵(如字典)。使用集合而不是其他資料型別的原因是,對於大量專案,集合比列表或元組快得多,並且集合提供快速的資料插入、刪除和成員資格測試。集合還支援數學集合運算,例如測試子集和查詢兩個集合的並集或交集。

>>> mind = set([42, 'a string', (23, 4)]) #equivalently, we can use {42, 'a string', (23, 4)}
>>> mind
set([(23, 4), 42, 'a string'])


>>> mind = set([42, 'a string', 40, 41])
>>> mind
set([40, 41, 42, 'a string'])
>>> mind = set([42, 'a string', 40, 0])
>>> mind
set([40, 0, 42, 'a string'])
>>> mind.add('hello')
>>> mind
set([40, 0, 42, 'a string', 'hello'])

請注意,集合是無序的,您新增到集合中的專案最終將位於不確定的位置,並且它也可能隨時更改。

>>> mind.add('duplicate value')
>>> mind.add('duplicate value')
>>> mind
set([0, 'a string', 40, 42, 'hello', 'duplicate value'])

集合不能包含單個值多次。與可以包含任何內容的列表不同,可以包含在集合中的資料型別受到限制。集合只能包含可雜湊的、不可變的資料型別。整數、字串和元組是可雜湊的;列表、字典和其他集合(除了凍結集,見下文)不是。

凍結集

[編輯 | 編輯原始碼]

凍結集和集合之間的關係就像元組和列表之間的關係。凍結集是集合的不可變版本。一個例子

>>> frozen=frozenset(['life','universe','everything'])
>>> frozen
frozenset(['universe', 'life', 'everything'])

其他資料型別

[編輯 | 編輯原始碼]

Python 還具有其他型別的序列,儘管這些序列的使用頻率較低,並且需要在使用前從標準庫中匯入。我們這裡只簡單介紹一下。

陣列
一個型別化的列表,陣列只能包含同構的值。
collections.defaultdict
一個字典,當找不到元素時,返回預設值而不是錯誤。
collections.deque
一個雙端佇列,允許快速操作佇列的兩端。
heapq
一個優先順序佇列。
佇列
一個執行緒安全的、多生產者、多消費者的佇列,用於多執行緒程式。請注意,列表也可以在單執行緒程式碼中用作佇列。

有關集合的更多說明,請參閱 資料結構/集合

第三方資料結構

[編輯 | 編輯原始碼]

Python 中一些有用的資料型別並不包含在標準庫中。其中一些在使用上非常專業化。我們將提及一些更廣為人知的第三方型別。

numpy.array
用於大量數值計算 => 請參閱numpy 部分
sorteddict
顧名思義,一個排序字典
  1. 編寫一個程式,將 5、10 和 "twenty" 放入列表中。然後從列表中刪除 10。
  2. 編寫一個程式,將 5、10 和 "twenty" 放入元組中。
  3. 編寫一個程式,將 5、10 和 "twenty" 放入集合中。將 "twenty"、10 和 5 放入另一個集合中,故意以不同的順序。打印出這兩個集合並注意它們的排序。
  4. 編寫一個程式,構造一個元組,其中一個元素是凍結集。
  5. 編寫一個程式,建立一個字典,將 1 對映到 "Monday",2 對映到 "Tuesday",等等。
[編輯 | 編輯原始碼]
華夏公益教科書