- Python 3.7從零開始學
- 劉宇宙
- 4315字
- 2019-12-06 14:02:24
3.1 通用序列操作
在講解列表和元組之前,本節先介紹Python中序列的通用操作,這些操作在列表和元組中都會用到。
Python中所有序列都可以進行一些特定操作,包括索引(indexing)、分片(slicing)、序列相加(adding)、乘法(multiplying)、成員資格、長度、最小值和最大值。
3.1.1 索引
序列是Python中最基本的數據結構。序列中的每個元素都分配一個數字,代表它在序列中的位置(索引),第一個索引是0,第二個索引是1,以此類推。
序列中所有元素都是有編號的,從0開始遞增??梢酝ㄟ^編號分別對序列的元素進行訪問。下面通過交互輸入的方式介紹一個通過編號取元素的例子。
>>> greeting='Hello'#定義變量greeting,并賦值Hello >>> greeting[0] #根據編號取元素,使用格式為:在中括號中輸入所取元素的編號值 'H' >>> greeting[1] 'e' >>> greeting[2] 'l'
可以看到,序列中的元素從0開始,從左向右依自然順序編號,元素可以通過編號訪問。獲取元素的方式為:在變量后加中括號,在中括號中輸入所取元素的編號值。這個格式需要記住。
類似于我們平時排隊,站成一排時,一般從左往右編號,編上序號后(一般從1開始編號,不會從0開始),當叫一個序號時,就會由序號對應到人。程序中的序列也是如此。
這里的編號就是索引,可以通過索引獲取元素。所有序列都可以通過這種方式進行索引。
提 示
字符串是由字符組成的序列。索引0指向第一個元素。比如在上面的示例中,索引0指向字母H,索引1指向字母e,索引2指向字母l。
上面的示例是從左往右通過編號獲取元素的,是否可以從右往左通過編號獲取元素呢?我們試一試,在交互模式下輸入:
>>> greeting[-1] 'o' >>> greeting[-2] 'l' >>> greeting[-3] 'l' >>> greeting[-4] 'e'
可以看到,Python的序列也可以從右開始索引,最右邊的元素索引值為-1,從右向左遞減。
在Python中,從左向右索引稱為正數索引,從右向左索引稱為負數索引。使用負數索引時,Python會從最后一個元素開始計數。最后一個元素的位置編號是-1。
提 示
最后一個元素的編號不是-0,跟數學中的概念一樣:?0=0,?0和0都指向第一個元素。
從上面的幾個示例可以看到,進行字符串的索引時都定義了一個變量,其實不定義變量也可以。下面來看一個例子,在交互模式下輸入:
>>> 'Hello'[0] 'H' >>> 'Hello'[1] 'e' >>> 'Hello'[-1] 'o' >>> 'Hello'[-2] 'l'
可以看到,直接使用索引,不定義變量進行引用也可以。直接使用索引的效果和定義變量的效果是一樣的。
如果函數返回一個序列,是否可以直接對結果進行索引操作呢?在交互模式下輸入:
>>> thirdth=input()[0] happy >>> thirdth 'h'
由輸出結果可以看到,直接對函數的返回結果進行了索引操作。
索引既可以對變量的引用操作,也可以直接操作序列,還可以操作函數的返回序列。
3.1.2 分片
索引用來對單個元素進行訪問,使用分片可以對一定范圍內的元素進行訪問,分片通過冒號相隔的兩個索引實現。在交互模式下輸入:
>>> number=[1,2,3,4,5,6,7,8,9,10] >>> number[1:3] #取索引為第一和第二的元素 [2, 3] >>> number[-3:-1] #負數表明從右開始計數,取得倒數第三和倒數第二的元素 [8, 9]
由操作結果可以看到,分片操作既支持正數索引,也支持負數索引,并且對于提取序列的一部分很方便。
分片操作的實現需要提供兩個索引作為邊界,第一個索引的元素包含在分片內,第二個索引的元素不包含在分片內。像數學里的a≤x<b,x是我們需要得到的元素,a是分片操作中的第一個索引,b是第二個索引,b不包含在x的范圍內。
對于上面的示例,假設需要訪問最后3個元素,使用正數索引可以這樣操作:
>>> number=[1,2,3,4,5,6,7,8,9,10] >>> number[7:10] #取最后3個元素 [8, 9, 10]
由以上輸入和我們前面對序列的定義可以得出,number的編號最大應該為9,編號為10指向的是第11個元素,是一個不存在的元素,但是由于在最后一個元素之后,因此能得到最后一個元素。這么做沒問題。如果需要從列表的結尾開始,即使用負數索引,怎么辦呢?我們嘗試看看,輸入如下:
>>> number=[1,2,3,4,5,6,7,8,9,10] >>> number[-3:-1] [8, 9]
結果沒有輸出最后一個元素。再試試使用索引0作為最后一個元素的下一個元素,輸入如下:
>>> number[-3:0] []
這個輸出結果有點奇怪,竟然一個數值都沒有。
事實上,只要在分片中最左邊的索引比它右邊的索引晚出現在序列中,結果就是一個空序列。比如上例中,-3代表倒數第3個元素,0代表第一個元素,倒數第3個元素比第一個元素晚出現,即排在第一個元素后面,所以得到的結果是空序列。
我們怎么通過負數索引的方式取得最后一個元素呢?這里有一個捷徑可以使用。如果需要取得的分片包括序列結尾的元素,只需將第二個索引設置為空即可。輸入如下:
>>> number[-3:] [8, 9, 10]
輸出結果和我們預期的一樣。
正數索引能否使用這種方式呢?輸入如下:
>>> number[0:] #從第一個元素開始輸出,輸出全部結果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> number[:0] #最后一個元素為第一個,輸出為空 [] >>> number[:3] #取得前3個元素 [1, 2, 3]
由輸出結果可以知道也適用于正數索引。
根據上述輸出結果可知,若需要輸出整個序列,則可以將兩個索引都設置為空。輸入如下:
>>> number[:] #取得整個數組 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
輸出結果是整個序列。
進行分片時,分片的開始點和結束點都需要指定(無論是直接指定還是間接指定),用這種方式取連續的元素沒有問題,但若要取序列中不連續的元素就比較麻煩,或者直接不能操作。比如要取序列number中的所有奇數,以一個序列展示出來,用前面的方法就不能實現了。
對于上面這種情況,Python為我們提供了另一個參數——步長(step length),該參數通常是隱式設置的。在普通分片中,步長是1。分片操作就是按照這個步長逐個遍歷序列的元素,遍歷后返回開始點和結束點之間的所有元素。也可以理解為默認步長是1,即沒有設置步長時,步長隱式設置值為1。輸入如下:
>>> number[0:10:1] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
由上面的示例可以看到,分片包含另一個數字。這種方式就是步長的顯式設置。看起來和隱式設置步長沒什么區別,得到的結果也和之前一樣。但若將步長設置為比1大的數,結果會怎樣呢?輸入如下:
>>> number[0:10:2] [1, 3, 5, 7, 9]
由上面的輸出結果可以看到,對于number序列,設置步長為2時,得到的結果就是我們前面想要的奇數序列。
由結果可知,步長設置為大于1的數時,會得到一個跳過某些元素的序列。例如,我們上面設置的步長為2,得到的序列是從開始到結束每隔1個元素的序列。比如還可以這樣使用:
>>> number[0:10:3] [1, 4, 7, 10] >>> number[2:6:3] [3, 6] >>> number[2:5:3] [3] >>> number[1:5:3] [2, 5]
由以上輸出結果可以看到,使用步長的方式還是很靈活的。
除了上面的使用方式外,設置前面兩個索引為空的捷徑也可以使用。操作如下:
>>> number[::3] [1, 4, 7, 10]
上面的操作將序列中每3個元素的第一個提取出來,前面兩個索引都設置為空。步長設置為0是否可行呢?輸入如下:
>>> number[::0] Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: slice step cannot be zero
輸出結果告訴我們步長不能為0。
步長是否可以為負數呢?輸入如下:
>>> number[10:0:-2] [10, 8, 6, 4, 2] >>> number[0:10:-2] [] >>> number[::-2] [10, 8, 6, 4, 2] >>> number[5::-2] [6, 4, 2] >>> number[:5:-2] [10, 8] >>> number[::-1] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] >>> number[10:0:-1] #第二個索引為0,取不到序列中的第一個元素 [10, 9, 8, 7, 6, 5, 4, 3, 2] >>> number[10::-1] #設置第二個索引為空,可以取到序列的第一個元素 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] >>> number[2::-1] #設置第二個索引為空,可以取到序列的第一個元素 [3, 2, 1] >>> number[2:0:-1] #第二個索引為0,取不到序列中的第一個元素 [3, 2]
上面的輸出結果好像不太好理解,使用負數步長時的結果怎么跟使用正數步長的結果相反呢?這就是正數步長和負數步長的不同。
對于正數步長,Python會從序列的頭部開始向右提取元素,直到最后一個元素;對于負數步長,則是從序列的尾部開始向左提取元素,直到第一個元素。正數步長必須讓開始點小于結束點,而負數步長必須讓開始點大于結束點。
提 示
通過示例可以看到,使用負數步長時,設置第二個索引為空才能取到序列的第一個元素。
3.1.3 序列相加
使用加號可以進行序列的連接操作,輸入如下:
>>> [1,2,3]+[4,5,6] [1, 2, 3, 4, 5, 6] >>> a=[1,2] >>> b=[5,6] >>> a+b [1, 2, 5, 6] >>> s='hello,' >>> w='world' >>> s+w 'hello,world'
由上面的輸出結果可以看到,數字序列可以和數字序列通過加號連接,連接后的結果還是數字序列;字符串序列也可以通過加號連接,連接后的結果還是字符串序列。數字序列是否可以和字符串序列相加,結果是數字序列還是字符串序列呢?輸入如下:
>>> [1,2]+'hello' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "str") to list >>> type([1,2]) #取得[1,2]的類型為list <class 'list'> >>> type('hello') #取得hello的類型為字符串 <class 'str'>
由上面的輸出結果可以看到,數字序列和字符串序列不能通過加號連接。錯誤提示的信息是:只能列表和列表相連。
由試驗結果可以得知:只有類型相同的序列才能通過加號進行序列連接操作,不同類型的序列不能通過加號進行序列連接操作。
3.1.4 乘法
注意此處的乘法并不是數學中定義的乘法。
用一個數字x乘以一個序列會生成新的序列。在新的序列中,原來的序列將被重復x次,這就是序列中的乘法。在交互模式下輸入:
>>> 'hello'*5 'hellohellohellohellohello' >>> [7]*10 [7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
從輸出結果看到,序列被重復了對應的次數,而不是做了數學中的乘法運算。
在Python中,序列的乘法有什么特殊之處呢?
如果要創建一個重復序列,就可以像上面的示例一樣乘以一個想要得到的序列長度的數字,這樣可以快速得到需要的列表,非常方便。
空列表可以簡單通過兩個中括號([])表示,表示里面什么東西都沒有。如果想創建一個占用10個或更多元素的空間,卻不包括任何有用內容的列表,該怎么辦呢?我們可以像上面的示例一樣乘以10或對應的數字,得到需要的空列表,也很方便。
如果要初始化一個長度為x的序列,就需要讓每個編碼位置上都是空值,此時需要一個值代表空值,即里面沒有任何元素,可以使用None。None是Python的內建值,確切含義是“這里什么也沒有”。例如,輸入如下:
>>> sq=[None]*5 #初始化sq為含有5個None的序列 >>> sq [None, None, None, None, None]
從示例我們可以看到,Python中的序列乘法可以幫助我們快速做一些初始化操作。序列乘法做一些重復操作、空列表和None初始化操作還是挺方便的。
3.1.5 成員資格
為了檢查一個值是否在序列中,Python為我們提供了in運算符。in運算符和前面討論過的運算符有些不同。in運算符用于檢驗某個條件是否為真,并返回檢驗結果,檢驗結果為真返回True,為假返回False。這種運算符稱作布爾運算符,返回的真值叫作布爾值。關于布爾運算符的更多內容會在后續章節中進行介紹。
下面我們嘗試使用in在交互模式下輸入:
>>> greeting='hello,world' >>> 'w' in greeting #檢測w是否在字符串中 True >>> 'a' in greeting False >>> users=['xiaomeng','xiaozhi','xiaoxiao'] >>> 'xiaomeng' in users #檢測字符串是否在字符串列表中 True >>> 'xiaohuai' in users False >>> numbers=[1,2,3,4,5] >>> 1 in numbers #檢測數字是否在數字列表中 True >>> 6 in numbers False >>> eng='** Study python is so happy!**' >>> '**' in eng #檢測一些特殊字符是否在字符串中 True >>> '$' in eng False >>> 'a' in numbers False >>> 3 in greeting Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'in <string>' requires string as left operand, not int
由上面的輸出結果可以看到,使用in可以很好地檢測字符或數字是否在對應的列表中。并且可以看出,數字類型不能在字符串類型中通過in進行成員資格檢測,而字符串類型可以在數字列表中通過in進行成員資格檢測。
3.1.6 長度、最小值和最大值
Python為我們提供了長度、最大值和最小值的內建函數,對應的內建函數分別為len、max和min。
這3個函數該怎么使用呢?在交互模式下輸入:
>>> numbers=[300,200,100,800,500] >>> len(numbers) 5 >>> max(numbers) 800 >>> min(numbers) 100 >>> max(5,3,10,7) 10 >>> min(7,0,3,-1) -1
由上面的結果可以看到,len函數返回序列中所包含元素的數量,max函數和min函數分別返回序列中最大和最小的元素。在該示例中,前面幾個函數的輸入參數都是序列,可以使用前面的解釋理解。max函數和min函數的參數不是一個序列,而是以多個數字直接作為參數,此處直接求取多個數字的最大值和最小值。
- HornetQ Messaging Developer’s Guide
- VMware View Security Essentials
- Expert C++
- Power Up Your PowToon Studio Project
- Twilio Best Practices
- iOS開發實戰:從零基礎到App Store上架
- STM32F0實戰:基于HAL庫開發
- Visual Basic程序設計與應用實踐教程
- Java程序設計:原理與范例
- Python Machine Learning Blueprints:Intuitive data projects you can relate to
- Simulation for Data Science with R
- Qt 4開發實踐
- Test-Driven iOS Development with Swift
- PostgreSQL 12 High Availability Cookbook
- Learning Alfresco Web Scripts