數據結構是以某種方式(如通過編號)組合起來的數據元素(如數、字符乃至其他數據結構)集合。在Python中,最基本的數據結構為序列(sequence)。序列中的每個元素都有編號,即其位置或索引,其中第一個元素的索引為0,第二個元素的索引為1,依此類推。在有些編程語言中,從1開始給序列中的元素編號,但從0開始指出相對于席列開頭的偏移量。這顯得更自然,同時可回繞到序列未尾,用負索引表示序列未尾元素的位置。序列是對列表和元組的有序數據結構的一種更高層次的抽象。
首先對序列進行概述,然后介紹一些適用于所有序列(包括列表和元組)的操作。這些操作也適用于一些示例中將使用的字符串,后面將全面介紹字符串操作。討論這些基本知識后,將著手介紹列表,看看它們有什么特別之處,然后討論元組。元組是一種特殊的序列,類似于列表,只是不能修改。其它編程語言似乎嗎似乎沒有元組這個概念。python引進元組后,很多代碼都可以寫得更加優雅和簡潔。
列表和元組的主要不同在于,列表是可以修改的,而元組不可以。這意味著列表適用于需要中途添加元素的情形,而元組適用于出于某種考慮需要禁止修改序列的情形。禁止修改序列通常出于技術方面的考慮,與Python的內部工作原理相關,這也是有些內置函數返回元組的原因所在。在你自己編寫程序時,幾乎在所有情況下都可使用列表來代替元組。一種例外情況是將元組用作字典鍵。在這種情況下不能使用列表來代替元組,因為字典鍵是不允許修改的。在需要處理一系列值時,序列很有用。在數據庫中,你可能使用序列來表示人,其中第一個元素為姓名,而第二個元素為年齡。如果使用列表來表示(所有元素都放在方括號內,并用逗號隔開),將類似于下面這樣:
edward = ["edware gummy", 45]john = ["john smith", 42]database = [edward, john]print(database)
因為python的變量是類似于java的引用,占用的空間是固定大小的,所以列表中放不同的類型也不會引起問題。
Python支持一種數據結構的基本概念,名為容器(container)。容器基本上就是可包含其他對象的對象。兩種主要的容器是序列(如列表和元組)和映射(如字典)。在序列中,每個元素都有編號,而在映射中,每個元素都有名稱(也叫鍵)。映射將在第4章詳細討論。有一種既不是序列也不是映射的容器它就是集合(set)。有其它語言基礎的同學可以進行類比記憶。
通用的序列操作
有幾種操作適用于所有序列,包括索引、切片、相加、相乘和成員資格檢查。另外,Python還提供了一些內置函數,可用于確定序列的長度以及找出序列中最大和最小的元素。還有一個重要的操作,它就是迭代(iteration)。對序列進行迭代意味著對其每個元素都執行特定的操作。
列表:Python的主力
列表很有用,但本節主要討論列表不同于元組和字符串的地方列表是可變的,即可修改其內容。另外,列表有很多特有的方法。
函數list
鑒于不能像修改列表那樣修改字符串,因此在有些情況下使用字符串來創建列表很有幫助。為此,可使用函數list。
list('Hello’)['h', 'e', 'l', 'l', 'o']
請注意,可將任何序列(而不僅僅是字符串)作為list的參數。
提示 要將字符列表(如前述代碼中的字符列表)轉換為字符串,可使用下面的表達式:
join(somelist)
其中somelist是要轉換的列表。
元組:不可修改的序列
與列表一樣,元組也是序列,唯一的差別在于元組是不能修改的(你可能注意到了,字符串也不能修。元組語法很簡單,只要將一些值用逗號分隔,就能自動創建一個元組。
>>> 1, 2,3(1,2,3)
如你所見,元組還可用圓括號括起(這也是通常采用的做法)
>>>(1,2,3)(1.2、3)
空元組用兩個不包含任何內容的圓括號表示。
>>>()
你可能會問,如何表示只包含一個值的元組呢?這有點特殊:雖然只有一個值,也必須在它后面加上逗
>>> 4242>>>42,(42,)>>>(42,)(42,)
最后兩個示例創建的元組長度為1,而第一個示例根本沒有創建元組。逗號至關重要,僅將值用圓括號括起不管用:(42)與42完全等效。但僅僅加上一個逗號,就能完全改變表達式的值。
>>>3*(40 + 2)126>>> 3*(40 + 2,)(42,42,42)
函數tuple的工作原理與list很像:它將一個序列作為參數,并將其轉換為元組曲。如果參數已經是元組,就原封不動地返回它,
>>>tuple([1,2,3])(1,2,3)>>>tuple('abc’)('a','b','c')tuple((1,2,3)(1,2,3)
你可能意識到了,元組并不太復雜,而且除創建和訪問其元素外,可對元組執行的操作不多。元組的創建及其元素的訪問方式與其他序列相同,
>>> x=1,2,3>>>x[1]2>>>x[0:2](1,2)
元組的切片也是元組,就像列表的切片也是列表一樣。為何要熟悉元組呢?原因有以下兩個
口 它們用作映射中的鍵(以及集合的成員),而列表不行。
口 有些內置函數和方法返回元組,這意味著必須跟它們打交道。只要不嘗試修改元組,與元組“打交道”通常意味著像處理列表一樣處理它們(需要使用元組沒有的index和count等方法時例外)
一般而言,使用列表足以滿足對序列的需求。
小結
下面來回顧一下介紹的一些最重要的概念。
口 序列:序列是一種數據結構,其中的元素帶編號(編號從0開始)。列表、字符串和元組都屬于序列,其中列表是可變的(你可修改其內容),而元組和字符串是不可變的(一旦創建,內容就是固定的)。要訪問序列的一部分,可使用切片操作:提供兩個指定切片起始和結束位置的索引。要修改列表,可給其元素賦值,也可使用賦值語句給切片賦值。
口 成員資格:要確定特定的值是否包含在序列(或其他容器)中,可使用運算符in。將運算符in用于字符串時情況比較特殊-----這樣可查找子串。
口方法:一些內置類型(如列表和字符串,但不包括元組)提供了很多有用的方法。方法有點像函數只是與特定的值相關聯。方法是面向對象編程的一個重要方面。
圖片1新函數總結
創建和使用字典
字典以類似于下面的方式表示:
phonebook={Alice : 2341’,'Beth':'9102','Cecil':'3258’}
字典由鍵及其相應的值組成,這種鍵-值對稱為項(item)。在前面的示例中,鍵為名字,而值為電話號碼。每個鍵與其值之間都用冒號(:)分隔,項之間用逗號分隔,而整個字典放在花括號內。空字典(沒有任何項)用兩個花括號表示,類似于下面這樣:。注意 在字典(以及其他映射類型)中,鍵必須是獨一無二的,而字典中的值無需如此。
函數dict
可使用函數dict從其他映射(如其他字典)或鍵-值對序列創建字典。
>>>items = [('name,Gumby'),('age’,42)]>>>d= dict(items){age:42,name:'Gumby'}>>>d [name ]Gumby
還可使用關鍵字實參來調用這個函數,如下所示:
>>>d= dict(name=’Gumby’, age=42)>>>d{'age’: 42,'name’: 'Gumby'}
盡管這可能是函數dict最常見的用法,但也可使用一個映射實參來調用它,這將創建一個字典,其中包含指定映射中的所有項。像函數list、tuple和str一樣,如果調用這個函數時沒有提供任何實參,將返回一個空字典。從映射創建字典時,如果該映射也是字典(畢競字典是Python中唯一的內置映射類型),可不使用函數dict,而是使用字典方法copy。