[python學習手冊-筆記]002.python核心資料型別

不願透露姓名的高楊發表於2020-11-14

python核心資料型別

本系列文章是我個人學習《python學習手冊(第五版)》的學習筆記,其中大部分內容為該書的總結和個人理解,小部分內容為相關知識點的擴充套件。

非商業用途轉載請註明作者和出處;商業用途請聯絡本人(gaoyang1019@hotmail.com)獲取許可。

先來解決一個書上沒搞懂的東西,字面量

百度百科給出的字面量的解釋:"在電腦科學中,字面量(literal)是用於表達原始碼中一個固定值的表示法(notation)。"

我表示沒看懂,然後又查了一下.所謂字面量,就是那些賦值等號後面的數字啊字串啊等等. 所以給出一個定性的解釋吧.

var = 10 #這個"10"就是字面量

python的內建物件

物件型別 字面量/構造示例
數字 1234, 3.1415
字串 "hello" b'a\x01c'
列表 [1,2,"word"], list(range(10))
字典 {"food":"tomato","price":6.66}, dict(hours=10)
元組 (1,2,"brady"),tuple('spam')
檔案 open("egg.txt")
集合 set("abc"),{'a','b','c'}
其他核心型別 型別,None,布林型
程式單元型別 函式,模組,類
Python實現相關型別 已編譯程式碼,呼叫棧跟蹤

數字型別

Python中的數字型別,除了支援常見的整數和浮點數之外,還有有虛部的附屬,固定精度的十進位制數字,帶分子和分母的有理數等等. 支援常見的算數運算.

字串

字串是通過""或者''括起來的任意文字.在python中單引號和雙引號的作用相同.

首先要明白字串的兩個特性:

  • python中的字串是一個序列,也就是說它是遵循可迭代協議的
  • 字串是一個不可改變的量(這個理解起來有點困難,稍後會說,先承認這一特性)

字串序列的操作

通過len()方法計算長度

In [2]: S = "spam"
In [3]: len(S)
Out[3]: 4

索引和切片

  1. 字串是一個序列,支援索引和for的遍歷

    在字串的索引中,負數表示逆向的索引,也就是從後往前.也就是說S[-1]相當於S[len(S)-1]

    In [4]: S[0]
    Out[4]: 's'
    In [5]: S[-1]
    Out[5]: 'm'
    In [6]: for s in S:
       ...:     print(s)
       ...:
    s
    p
    a
    m
  2. 字串支援分片操作

    In [7]: S='hello'
    # 取第三位到第五位之間的子串
    In [8]: S[2:4]
    Out[8]: 'll'
    # 從第三位取到結尾
    In [9]: S[2:]
    Out[9]: 'llo'
    # 取前三位
    In [10]: S[:3]
    Out[10]: 'hel'
    # 從開始擷取到倒數第二位之前
    In [11]: S[:-2]
    Out[11]: 'hel'

    注意,分片操作的時候,X[I:J]表示的是從X[I]開始,到X[J]結束,但是不包括X[J]

  3. 字串的拼接和重複

    字串支援通過+ 進行連線. 也可以通過*進行重複.

    但是注意,這不代表字串是可以改變的. 比如以下程式碼3-4行中,S+'xyz'.

    這並不是改變了原有字串S,而是開闢新的記憶體空間,將原有字串S和'xyz'進行連線,生成一個新的量.

    In [12]: S = "spam"

    In [13]: S+'xyz'
    Out[13]: 'spamxyz'

    In [14]: S*3
    Out[14]: 'spamspamspam'

    這裡,對於操作符+對於不同的型別而言有著不同的作用. 比如在數字型別中表示算數運算中的加法,在字串中表示字串連線. 這一特性就是傳說中的多型,也稱之為運算子過載. 這是Python中的一個極其重要的設計思路.

不可變性

字串在Python中是一個不可變的字面量. 在python核心型別中,字串,數字,元組都是不可變的. 而列表,字典,集合是可變的.

當然,通過前面的學習,某些操作,彷彿可以改變字串. 但是這裡要說的是,這種所謂的"改變"字串,實際上是生成新的字面量,而不是改變原有字面量.

特性型別的方法(內建方法)

Python對於不同的型別,內建了一些便捷的方法可以使用. 也就是我們所謂的內建方法. 相關的內建方法可以在python官網的文件進行查詢.這也是後面我們要學習內容的一部分.

In [15]: S = "Spam"
# 字串替換
In [17]: S.replace('pa','xz')
Out[17]: 'Sxzm'
    
In [18]: line = "aaa,bbb,ccc"
# 字串分割
In [19]: line.split(',')
Out[19]: ['aaa''bbb''ccc']

在python中,我們可以通過dir()方法檢視在其作用域內,該型別所支援的屬性和方法.

In [20]: dir(S)
Out[20]:['__add__''__class__''__contains__''__delattr__''__dir__''__doc__''__eq__''__format__''__ge__''__getattribute__''__getitem__''__getnewargs__''__gt__''__hash__''__init__''__init_subclass__''__iter__''__le__''__len__''__lt__''__mod__''__mul__''__ne__''__new__''__reduce__''__reduce_ex__''__repr__''__rmod__''__rmul__''__setattr__''__sizeof__''__str__''__subclasshook__''capitalize''casefold''center''count''encode''endswith''expandtabs''find''format''format_map''index''isalnum''isalpha''isascii''isdecimal''isdigit''isidentifier''islower''isnumeric''isprintable''isspace''istitle''isupper''join''ljust''lower''lstrip''maketrans''partition''replace''rfind''rindex''rjust''rpartition''rsplit''rstrip''split''splitlines''startswith''strip''swapcase''title''translate''upper''zfill']

轉義字元和unicode字串

python與其他語言一樣,支援'\'的轉義字元. 比如常見的\n\t

另外python原生支援unicode字串. (關於unicode字串,後續會有相關文章介紹)

列表

列表是類似C語言中陣列的一種東西. 但是相比C語言的陣列,python的列表更加靈活:

  • python的列表不侷限其內的資料型別. 同一個列表中可以存放不同型別的資料
  • python的列表是可變長的.
  • python的列表支援推導表示式
# python的 列表中可以存放不同資料型別的資料
In [23]: L = [1,2,'egg']

In [24]: len(L)
Out[24]: 3
# 列表也支援拼接操作
In [25]: L + [4,5,6]
Out[25]: [12'egg'456]
# 列表同樣支援重複操作
In [26]: L*2
Out[26]: [12'egg'12'egg']

列表的邊界檢查

python的列表沒有固定的大小,但是同樣有邊界檢查,不允許引用不存在的元素. 也就是說,列表結尾之外的索引是不支援的.

In [27]: L = [1,2,3]

In [28]: L[3]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-28-28c5e42e8527> in <module>
----> 1 L[3]

IndexError: list index out of range

如果我們需要增加列表的元素,可以使用內建方法append

In [29]: L[3]=4
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-29-3e20e34dcd62> in <module>
----> 1 L[3]=4

IndexError: list assignment index out of range

In [30]: L.append(4)

In [31]: L
Out[31]: [1234]

列表推導式

這就是python強大的地方了,列表中除了可以存放已知的,實際的資料外,還可以通過公式來生成一個列表. 這在矩陣處理中十分有用.

In [32]: M = [[1,2,3],[4,5,6],[7,8,9]]

In [33]: M
Out[33]: [[123], [456], [789]]

In [36]: diag=[M[i][i] for i in [0,1,2]]
In [37]: diag
Out[37]: [159]
# 傳說中的列表生成式    
In [38]: L = [[x,x/2,x*2for x in range(-6,7,2if x>0]

In [39]: L
Out[39]: [[21.04], [42.08], [63.012]]

字典

字典有很多的名字,字典,雜湊,雜湊列表,對映等等. 字典不是一種序列,它是一種對映.是通過鍵-值對的形式來儲存資料的.

它的儲存原理和列表不同. 簡答來說,字典的儲存是將鍵(key)通過雜湊函式進行轉換,得到一個地址,然後將值(value)放入該地址.

那也就是說,字典的查詢速度和其大小無關. 所以對於搜尋來說,字典比列表更合適.

字典的構造

這裡列舉出了字典的三種構造方式.

In [42]: bob = {'name':'bob','age':40,'job':'dev'}

In [43]: bob
Out[43]: {'name''bob''age'40'job''dev'}

In [44]: bob2 = dict(name='bob',age=40,job='dev')

In [45]: bob2
Out[45]: {'name''bob''age'40'job''dev'}

In [46]: bob3 = dict(zip(['name','job','age'],['bob','dev',40]))

In [47]: bob3
Out[47]: {'name''bob''job''dev''age'40}

關於zip()方法的用法,後續的文章會講到

字典中的值可以是簡單的數值和字串,也可以是其他型別,比如:

In [48]: bob4 = {'name':{"first":'bob','last':'Smith'},'job':['dev','test'],'age':40}

In [49]: bob4
Out[49]: {'name': {'first''bob''last''Smith'}, 'job': ['dev''test'], 'age'40}

字典的鍵

字典的鍵是其索引,我們可以通過鍵來訪問對應的資料,也可以通過鍵來增加新的資料. 但是對於不存在的鍵,同樣是不支援訪問的.

In [50]: abc = {'A':'a','B':'b','C':'c'}

In [51]: abc['B']
Out[51]: 'b'

In [52]: abc['D']='d'

In [53]: abc
Out[53]: {'A''a''B''b''C''c''D''d'}

In [54]: abc['E']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-54-15e1b0b37eaa> in <module>
----> 1 abc['E']

KeyError: 'E'

那麼在訪問字典資料之前,為了避免這種錯誤,我們可以檢查一下我們要訪問的鍵是否存在.

先說一個最容易理解的方式,通過if語句進行檢查

In [57]: if 'D' in abc:
    ...:     print('hit')
    ...: if not 'F' in abc:
    ...:     print('miss')
    ...:
hit
miss

其次還可以使用get方法來進行檢查,關於get方法,做一個簡單的解釋.

dict.get(key, default=None) get方法可以通過鍵來訪問資料,如果訪問不到則返回第二個引數.

In [58]: value = abc.get('D',0)

In [59]: value
Out[59]: 'd'

In [60]: value = abc.get('F',0)

In [61]: value
Out[61]: 0

另外,字典還支援通過keys方法返回一個包含所有鍵的可迭代物件.

In [67]: Ks = abc.keys()

In [71]: for key in Ks:
    ...:     print(key)
    ...:
A
B
C
D

元組

python中的元組可以理解為是一種不可改變的列表. 用來表示確定的元素的集合. 語法很簡單.如下:

In [72]: T1 = (1,2,3)

In [73]: type(T1)
Out[73]: tuple

In [74]: T1[1]
Out[74]: 2

In [77]: T1.count(2)
Out[77]: 1

In [78]: T1 +(4,5,6)
Out[78]: (123456)

元組同樣像列表那樣支援分片操作和索引. 但是元組不支援append等方法. 不準確的說,元組其實更像一個可以存放任意的型別的"字元"串.

那麼,既然我們已經有了列表,為什麼還需要元組呢?

元組和列表的主要區別在於,元組是不可改變的. 在一些特定的場景下,元組提供了一種完整性的約束.

檔案

檔案是一種比較特殊的型別,沒有特定的字面量可以建立檔案. 一般我們是通過open函式傳遞一個檔名和操作符來生成檔案控制程式碼.

In [79]: f = open('data.txt','wb')

In [81]: f.write(b'hello world')
Out[81]: 11

In [83]: f.close()

集合

python集合不是序列,也不是對映. 它是python中到目前為止,唯一一種不可變的物件的無序集合. 其實python中的集合其實就是數學上所謂的集合. 對,就是那個我們初中學習的交集,並集啥啥啥的玩意兒.

集合的建立有兩種方法:

In [85]: X = {1,2,3,4}

In [87]: Y = set([3,4,5,6])

In [88]: X
Out[88]: {1234}

In [89]: Y
Out[89]: {3456}
# 交集
In [90]: X&Y
Out[90]: {34}
# 並集
In [91]: X|Y
Out[91]: {123456}
# 差集
In [92]: X-Y
Out[92]: {12}
# X是否為Y的超集
In [93]: X>Y
Out[93]: False

其他資料型別

除了以上介紹的核心型別之外,python中的資料型別還有:

  • 程式碼塊
  • 布林值
  • 函式
  • 模組

後續再詳細講解

相關文章