每天資訊厲害了!頭一次見有大佬把字串和常用資料結構,詳解得如此清晰明瞭

菜單

厲害了!頭一次見有大佬把字串和常用資料結構,詳解得如此清晰明瞭

使用字串

第二次世界大戰促使了現代電子計算機的誕生,最初計算機被應用於導彈彈道的計算,而在計算機誕生後的很多年時間裡,計算機處理的資訊基本上都是數值型的資訊。世界上的第一臺電子計算機叫ENIAC(電子數值積分計算機),誕生於美國的賓夕法尼亞大學,每秒鐘能夠完成約5000次浮點運算。隨著時間的推移,雖然數值運算仍然是計算機日常工作中最為重要的事情之一,但是今天的計算機處理得更多的資料可能都是以文字的方式存在的,如果我們希望透過Python程式操作本這些文字資訊,就必須要先了解字串型別以及與它相關的知識。

所謂

字串

,就是由零個或多個字元組成的有限序列,一般記為

在Python程式中,如果我們把單個或多個字元用單引號或者雙引號包圍起來,就可以表示一個字串。

可以在字串中使用

\

(反斜槓)來表示轉義,也就是說

\

後面的字元不再是它原來的意義,例如:

\n

不是代表反斜槓和字元n,而是表示換行;而

\t

也不是代表反斜槓和字元t,而是表示製表符。所以如果想在字串中表示

要寫成

\’

,同理想表示

\

要寫成

\\

。可以執行下面的程式碼看看會輸出什麼。

\

後面還可以跟一個八進位制或者十六進位制數來表示字元,例如

\141

\x61

都代表小寫字母

a

,前者是八進位制的表示法,後者是十六進位制的表示法。也可以在

\

後面跟Unicode字元編碼來表示字元,例如

\u9a86\u660a

代表的是中文“駱昊”。執行下面的程式碼,看看輸出了什麼。

如果不希望字串中的

\

表示轉義,我們可以透過在字串的最前面加上字母

r

來加以說明,再看看下面的程式碼又會輸出什麼。

Python為字串型別提供了非常豐富的運算子,我們可以使用

+

運算子來實現字串的拼接,可以使用

*

運算子來重複一個字串的內容,可以使用

in

not in

來判斷一個字串是否包含另外一個字串(成員運算),我們也可以用

[]

[:]

運算子從字串取出某個字元或某些字元(切片運算),程式碼如下所示。

在Python中,我們還可以透過一系列的方法來完成對字串的處理,程式碼如下所示。

我們之前講過,可以用下面的方式來格式化輸出字串。

當然,我們也可以用字串提供的方法來完成字串的格式,程式碼如下所示。

Python 3。6以後,格式化字串還有更為簡潔的書寫方式,就是在字串前加上字母

f

,我們可以使用下面的語法糖來簡化上面的程式碼。

除了字串,Python還內建了多種型別的資料結構,如果要在程式中儲存和操作資料,絕大多數時候可以利用現有的資料結構來實現,最常用的包括列表、元組、集合和字典。

使用列表

不知道大家是否注意到,剛才我們講到的字串型別(

str

)和之前我們講到的數值型別(

int

float

)有一些區別。數值型別是標量型別,也就是說這種型別的物件沒有可以訪問的內部結構;而字串型別是一種結構化的、非標量型別,所以才會有一系列的屬性和方法。接下來我們要介紹的列表(

list

),也是一種結構化的、非標量型別,它是值的有序序列,每個值都可以透過索引進行標識,定義列表可以將列表的元素放在

[]

中,多個元素用

進行分隔,可以使用

for

迴圈對列表元素進行遍歷,也可以使用

[]

[:]

運算子取出列表中的一個或多個元素。

下面的程式碼演示瞭如何定義列表、如何遍歷列表以及列表的下標運算。

下面的程式碼演示瞭如何向列表中新增元素以及如何從列表中移除元素。

和字串一樣,列表也可以做切片操作,透過切片操作我們可以實現對列表的複製或者將列表中的一部分取出來創建出新的列表,程式碼如下所示。

下面的程式碼實現了對列表的排序操作。

生成式和生成器

我們還可以使用列表的生成式語法來建立列表,程式碼如下所示。

除了上面提到的生成器語法,Python中還有另外一種定義生成器的方式,就是透過

yield

關鍵字將一個普通函式改造成生成器函式。下面的程式碼演示瞭如何實現一個生成斐波拉切數列的生成器。所謂斐波拉切數列可以透過下面遞迴的方法來進行定義:

使用元組

Python中的元組與列表類似也是一種容器資料型別,可以用一個變數(物件)來儲存多個數據,不同之處在於元組的元素不能修改,在前面的程式碼中我們已經不止一次使用過元組了。顧名思義,我們把多個元素組合到一起就形成了一個元組,所以它和列表一樣可以儲存多條資料。下面的程式碼演示瞭如何定義和使用元組。

這裡有一個非常值得探討的問題,我們已經有了列表這種資料結構,為什麼還需要元組這樣的型別呢?

元組中的元素是無法修改的,事實上我們在專案中尤其是

多執行緒

環境(後面會講到)中可能更喜歡使用的是那些不變物件(一方面因為物件狀態不能修改,所以可以避免由此引起的不必要的程式錯誤,簡單的說就是一個不變的物件要比可變的物件更加容易維護;另一方面因為沒有任何一個執行緒能夠修改不變物件的內部狀態,一個不變物件自動就是執行緒安全的,這樣就可以省掉處理同步化的開銷。一個不變物件可以方便的被共享訪問)。所以結論就是:如果不需要對元素進行新增、刪除、修改的時候,可以考慮使用元組,當然如果一個方法要返回多個值,使用元組也是不錯的選擇。

元組在建立時間和佔用的空間上面都優於列表。我們可以使用sys模組的getsizeof函式來檢查儲存同樣的元素的元組和列表各自佔用了多少記憶體空間,這個很容易做到。我們也可以在ipython中使用魔法指令%timeit來分析建立同樣內容的元組和列表所花費的時間,下圖是我的macOS系統上測試的結果。

使用集合

Python中的集合跟數學上的集合是一致的,不允許有重複元素,而且可以進行交集、並集、差集等運算。

可以按照下面程式碼所示的方式來建立和使用集合。

向集合新增元素和從集合刪除元素。

集合的成員、交集、並集、差集等運算。

說明:

Python中允許透過一些特殊的方法來為某種型別或資料結構自定義運算子(後面的章節中會講到),上面的程式碼中我們對集合進行運算的時候可以呼叫集合物件的方法,也可以直接使用對應的運算子,例如

&

運算子跟intersection方法的作用就是一樣的,但是使用運算子讓程式碼更加直觀。

使用字典

字典是另一種可變容器模型,Python中的字典跟我們生活中使用的字典是一樣一樣的,它可以儲存任意型別物件,與列表、集合不同的是,字典的每個元素都是由一個鍵和一個值組成的“鍵值對”,鍵和值透過冒號分開。下面的程式碼演示瞭如何定義和使用字典。