python 中的序列
python 中的序列
序列概述
Python 內建了多種序列,比如列表、元組和字串。
列表和元組的主要不同在於:列表是可以修改的,而元組不可以。
在需要處理一系列值時,序列很有用。在資料庫中,你可能使用序列來表示人,其中第一個元素為姓名,第二個元素為年齡。如果使用列表來表示,將類似於下面這樣:
>>> edward = ['Edward Gumby', 42]
要點是:所有元素都放在方括號內,並用逗號隔開。
有的人喜歡把列表看成是 C 語言中的陣列。它們確實有相似性,但請你注意:C 語言中的陣列都是相同型別的元素,而 Python 的列表可以是不同型別的元素。
序列內還可以包含其他序列,比如:
>>> edward = ['Edward Gumby', 42]
>>> john = ['John Smith', 50]
>>> database = [edward, john]
>>> database
[['Edward Gumby', 42], ['John Smith', 50]]
注意
Python支援一種資料結構的基本概念,叫做“容器”(container)。容器基本上就是可包含其他物件的物件。兩種主要的容器是序列(如列表和元組)和對映(如字典)。在序列中,每個元素都有編號,而在對映中,每個元素都有鍵。有一種既不是序列也不是對映的容器,它就是集合(set)。
通用的序列操作
有幾種操作適用於所有序列,這些操作是索引、切片、相加、相乘、成員資格檢查和迭代等。另外,Python 還提供了一些內建函式,可用於確定序列的長度以及找出序列中最大和最小的元素。
索引(indexing)
序列中的所有元素都有編號——從0開始遞增。你可像下面這樣使用編號來訪問各個元素:
>>> greeting = 'Hello'
>>> greeting[0]
'H'
其實這和 C 語言中的字串很像。
字串就是由字元組成的序列。索引0指向第一個元素,這裡為字母H。不同於其他一些語言,Python 沒有專門用於表示字元的型別,因此一個字元就是隻包含一個元素的字串。
當你使用負數索引時,Python 將從右(即從最後一個元素)開始往左數,因此 -1 是最後一個元素的位置。
>>> greeting[-1]
'o'
對於字串字面量(以及其他的序列字面量),可直接對其執行索引操作,無需先將其賦給變數。
>>> 'Hello'[1]
'e'
其實在 C 語言中也可以這樣,比如:
#include <stdio.h>
int main(void)
{
printf("%c\r\n", "HelloWorld"[1]);
return 0;
}
以上這段程式碼的執行結果是:
e
如果函式呼叫返回一個序列,可直接對其執行索引操作。例如,如果你只想獲取使用者輸入的年份的第4位,可這樣做:
In [3]: fourth = input("Year : ")[3]
Year : 1998
In [4]: fourth
Out[4]: '8'
以上操作是在 ipython 中演示的,ipython 是什麼呢?
IPython provides a rich architecture for interactive computing with:
- A powerful interactive shell.
- A kernel for Jupyter.
- Support for interactive data visualization and use of GUI toolkits.
- Flexible, embeddable interpreters to load into your own projects.
- Easy to use, high performance tools for parallel computing.
—— 摘自 https://ipython.org/
切片(slicing)
除了使用索引來訪問單個元素外,還可使用切片(slicing)來訪問特定範圍內的元素。為此,可使用兩個索引,並用冒號分隔,比如
In [5]: nums=[1,2,3,4,5,6,7,8,9,10]
In [6]: nums[3:6]
Out[6]: [4, 5, 6]
In [7]: nums[0:1]
Out[7]: [1]
注意:第一個索引是包含的第一個元素的編號,但第二個索引是切片後餘下的第一個元素的編號。
簡而言之,你提供兩個索引來指定切片的邊界,其中第一個索引指定的元素包含在切片內,但第二個索引指定的元素不包含在切片內。
利用簡寫
假設你要訪問前述列表 nums 中的最後三個元素,可以這樣寫:
>>> nums[7:10]
[8, 9, 10]
在這裡,索引10指的是第11個元素,雖然它並不存在,但確實是到達最後一個元素後再前進一步的位置。
切片中也可使用負數索引。
>>> nums[-3:-1]
[8, 9]
然而,這樣好像無法包含最後一個元素。如果使用索引0,即到達列表末尾後再前進一步所處的位置,結果將如何呢?
在 ipython 中的結果如下:
In [5]: nums[-3:0]
Out[5]: []
結果並不是你想要的。事實上,執行切片操作時,如果第一個索引指定的元素位於第二個索引指定的元素後面(在這裡,倒數第3個元素位於第1個元素後面),結果就為空序列。
還好,我們可以使用一種簡寫:如果切片結束於序列末尾,可省略第二個索引。
In [6]: nums[-3:]
Out[6]: [8, 9, 10]
同理,如果切片始於序列開頭,可省略第一個索引。
In [7]: nums[:3]
Out[7]: [1, 2, 3]
要複製整個序列,可將兩個索引都省略,在方括號內只留一個冒號。
In [8]: nums[:]
Out[8]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
步長
執行切片操作時,你顯式或隱式地指定起點和終點,但通常省略了另一個引數,即步長。預設步長為1。這意味著從一個元素移到下一個元素,因此切片包含起點和終點之間的所有元素。
In [9]: nums[0:10:1]
Out[9]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
如果指定的步長大於1,將跳過一些元素。例如,步長為2時,將從起點和終點之間每隔一個元素提取一個元素。
In [10]: nums[0:10:2]
Out[10]: [1, 3, 5, 7, 9]
In [11]: nums[0:10:3]
Out[11]: [1, 4, 7, 10]
顯式地指定步長時,也可使用前述簡寫。例如,要從序列中每隔3個元素提取1個,只需提供步長4即可。
In [12]: nums[::4]
Out[12]: [1, 5, 9]
當然,步長不能為0,否則無法向前移動。
In [14]: nums[1:7:0]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-7219eb36c975> in <module>()
----> 1 nums[1:7:0]
ValueError: slice step cannot be zero
步長可以為負數,即從右向左提取元素。
In [15]: nums[::-1]
Out[15]: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
In [16]: nums[10:0:-2]
Out[16]: [10, 8, 6, 4, 2]
上面的結果,有人會疑惑。他這樣想:從10開始,也就是第11個元素,即最後一個元素的後面,然後向左走2步,應該是9,7,5,3,1 才對。
開始我也挺疑惑的,後來才明白,因為沒有10,最多是9,所以這裡的10就相當於9。
In [19]: nums[9:0:-2]
Out[19]: [10, 8, 6, 4, 2]
In [20]: nums[0:10:-2]
Out[20]: []
上面這個結果又是為什麼呢?
步長為負數時,第一個索引必須比第二個索引大。步長為正表示從左向右走,為負表示從右向左走。想象有一個數軸,從0向左走,是走不到10的,所以結果為空。
In [22]: nums[::-2]
Out[22]: [10, 8, 6, 4, 2]
當省略起始和結束索引時,Python 竟然執行了正確的操作:步長為正數時,它從起點移到終點,而步長為負數時,它從終點移到起點。
In [23]: nums
Out[23]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [24]: nums[:5:-2]
Out[24]: [10, 8]
In [25]: nums[5::-2]
Out[25]: [6, 4, 2]
請看第4行,省略的索引,到底是左邊的起點還是右邊的終點呢?因為步長是負數,所以一定是從右往左走,所以省略的是右邊的10;
第7行,因為步長為負數,所以應該從右向左,所以省略的索引是0;
In [26]: nums[10:5:-2]
Out[26]: [10, 8]
In [27]: nums[5:0:-2]
Out[27]: [6, 4, 2]
可以看到,和之前的結果是一樣的。
序列相加
可使用加法運算子來拼接序列。
In [28]: [1,2,3]+[4,5,6,7]
Out[28]: [1, 2, 3, 4, 5, 6, 7]
In [29]: "hello"+" "+"world"
Out[29]: 'hello world'
一般而言,不能拼接不同型別的序列。
In [30]: [1,2,3]+"hello"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-9346ef22b4d4> in <module>()
----> 1 [1,2,3]+"hello"
TypeError: can only concatenate list (not "str") to list
乘法
將序列與數 N 相乘時,將重複這個序列 N 次來建立一個新序列:
In [31]: "H"*6
Out[31]: 'HHHHHH'
In [32]: 10*"Hello"
Out[32]: 'HelloHelloHelloHelloHelloHelloHelloHelloHelloHello'
In [34]: [32,1]*3
Out[34]: [32, 1, 32, 1, 32, 1]
None、空列表和初始化
空列表是使用不包含任何內容的兩個方括號表示的。
In [43]: list=[]
In [44]: list
Out[44]: []
如果要建立一個可包含10個元素的列表,但沒有任何有用的內容,你可以使用[0]*10
,這將建立一個包含10個零的列表。然而,在有些情況下,你可能想使用表示“什麼都沒有”的值,在這種情況下,可使用 None
。在Python中,None
表示什麼都沒有。因此,要將列表的長度初始化為10,可像下面這樣做:
In [35]: seq=[None]*10
In [36]: seq
Out[36]: [None, None, None, None, None, None, None, None, None, None]
成員資格
要檢查特定的值是否包含在序列中,可使用運算子in
。它檢查是否滿足指定的條件,並返回相應的值:滿足時返回True
,不滿足時返回False
。這樣的運算子稱為布林運算子,而前述真值稱為布林值。
下面是一些例子。
In [48]: permission='rw'
In [49]: 'w' in permission
Out[49]: True
In [50]: 'x' in permission
Out[50]: False
記住 w 兩側要加引號。否則會報錯。
In [51]: w in permission
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-51-7a03fc4c0ccc> in <module>()
----> 1 w in permission
NameError: name 'w' is not defined
In [56]: option=['a','b','c']
In [57]: input("a/b/c: ") in option
a/b/c: b
Out[57]: True
In [58]: input("a/b/c: ") in option
a/b/c: d
Out[58]: False
In [59]: subject = '$$$ Get rich now!!! $$$'
In [60]: "$$" in subject
Out[60]: True
如上所示,可使用運算子 in 來檢查指定的字串是否為另一個字串的子串。
長度、最小值和最大值
內建函式len、min和max很有用,其中函式len返回序列包含的元素個數,而min和max分別返回序列中最小和最大的元素。
In [67]: numbers =[100, 77, 12]
In [68]: len(numbers)
Out[68]: 3
In [69]: max(numbers)
Out[69]: 100
In [70]: min(numbers)
Out[70]: 12
In [71]: subject="Hello!"
In [72]: len(subject)
Out[72]: 6
In [64]: my_string = "abcdefg"
In [65]: max(my_string)
Out[65]: 'g'
In [66]: min(my_string)
Out[66]: 'a'
【End】
參考資料
《Python基礎教程(第三版)》,人民郵電出版社
相關文章
- Python中的有序序列有哪些Python
- Python中序列化/反序列化JSON格式的資料PythonJSON
- Python中物件序列化和反序列化Python物件
- 『無為則無心』Python序列 — 20、Python中的元組Python
- 『無為則無心』Python序列 — 23、Python序列的公共APIPythonAPI
- python的序列化和反序列化Python
- 『無為則無心』Python序列 — 24、Python序列的推導式Python
- Python中巢狀自定義型別的JSON序列化與反序列化Python巢狀型別JSON
- 談下python微服務中的序列化場景Python微服務
- python sequence序列Python
- Python實用技法第15篇:篩選序列中的元素Python
- Python 序列化(Python IO)Python
- Python的文字和位元組序列Python
- Python技法-序列拆分Python
- python 時間序列Python
- python序列資料型別之序列資料的基本操作Python資料型別
- Java中的序列化與反序列化Java
- hadoop中的序列化Hadoop
- python筆記(一):序列Python筆記
- Python 時間序列分析Python
- Python基礎03 序列Python
- 第2章 Python序列Python
- [譯] Python 的時間序列分析:簡介Python
- Python3序列賦值、序列解包詳解(下)Python賦值
- python 反序列化漏洞Python
- python序列列表怎麼排序?Python排序
- fluent python讀書筆記2—Python的序列型別1Python筆記型別
- fluent python 讀書筆記 2–Python的序列型別2Python筆記型別
- 說說 Python 序列增量賦值的效率Python賦值
- 『無為則無心』Python序列 — 17、Python字串操作的常用APIPython字串API
- [譯] Swift 中的惰性序列及其原理Swift
- Swift 中的 JSON 反序列化SwiftJSON
- Python可迭代序列反轉Python
- python 同時迭代多個序列Python
- HTML5中有序列表和無序列表的寫法HTML
- JavaScript 中URL 查詢字串(query string)的序列與反序列化JavaScript字串
- Python學習——序列化與反序列化-json&picklePythonJSON
- Python常用標準庫(pickle序列化和JSON序列化)PythonJSON