跳到內容

Python 程式設計/資料型別

來自華夏公益教科書,開放的書籍,開放的世界


資料型別決定一個物件是否可以執行某些操作,或者是否沒有意義。其他程式語言通常透過確保物件永遠不會儲存在將對其執行操作的位置來確定操作對物件是否有意義(這種 型別系統 稱為靜態型別)。Python 不會這樣做。相反,它將物件的型別與物件一起儲存,並在執行操作時檢查該操作對該物件是否有意義(這稱為動態型別)。

內建資料型別

[編輯 | 編輯原始碼]

Python 的內建(或標準)資料型別可以分成幾個類別。遵循官方 Python 文件中使用的層次結構方案,它們是 **數值型別、序列、集合和對映**(以及此處未進一步討論的其他一些型別)。如以下所述,某些型別僅在語言的某些版本中可用。

  • 布林值:內建值 TrueFalse 的型別。在條件表示式中以及您想要表示某個條件的真假性時很有用。通常可以與整數 1 和 0 互換。事實上,條件表示式將接受任何型別的值,將特殊值(如布林值 False、整數 0 和空字串 "")視為等同於 False,並將所有其他值視為等同於 True

數值型別

  • int:整數;在 Python 2.x 中等效於 C 中的 longs,在 Python 3.x 中長度不受限制
  • long:長度不受限制的長整數;僅存在於 Python 2.x 中
  • float:浮點數,等效於 C 中的 doubles
  • complex:複數

序列

  • str:字串;在 Python 2.x 中表示為 8 位字元的序列,但在 Python 3.x 中表示為 Unicode 字元的序列(在 U+0000 - U+10FFFF 範圍內)
  • bytes:0-255 範圍內的整數序列;僅在 Python 3.x 中可用
  • 位元組陣列:與位元組類似,但可變(見下文);僅在 Python 3.x 中可用
  • 列表
  • 元組

集合

  • set:唯一物件的無序集合;從 Python 2.6 開始作為標準型別可用
  • frozenset:與 set 類似,但不可變(見下文);從 Python 2.6 開始作為標準型別可用

對映

  • dict:Python 字典,也稱為雜湊表或關聯陣列,這意味著列表中的一個元素與一個定義相關聯,類似於 Java 中的 Map

其他一些型別,例如型別和可呼叫物件

可變物件與不可變物件

[編輯 | 編輯原始碼]

一般來說,Python 中的資料型別可以根據該型別物件的可變性或不可變性來區分。不可變型別物件的內容在建立後無法更改。

一些不可變型別 一些可變型別
  • int、float、complex
  • str
  • bytes
  • 元組
  • frozenset
  • bool
  • array
  • bytearray
  • 列表
  • set
  • dict

只有可變物件支援原地更改物件的方法,例如重新分配序列切片,這將適用於列表,但會對元組和字串引發錯誤。

重要的是要了解,Python 中的變數實際上只是對記憶體中物件的引用。如果您將一個物件分配給一個變數,如下所示,

a = 1
s = 'abc'
l = ['a string', 456, ('a', 'tuple', 'inside', 'a', 'list')]

您真正做的只是讓這個變數(a, s,或者l)指向該物件(1, 'abc', ['a string', 456, ('a', 'tuple', 'inside', 'a', 'list')]),它被儲存在記憶體中的某個位置,作為訪問它的便捷方法。如果您重新分配一個變數,如下所示

a = 7
s = 'xyz'
l = ['a simpler list', 99, 10]

您將使該變數指向一個不同的物件(在我們示例中是新建立的物件)。如上所述,只有可變物件可以在原地更改(l[0] = 1在我們的示例中沒問題,但是s[0] = 'a'會引發錯誤)。當操作沒有明確要求原地更改時,這會變得很棘手,例如對於+=(增量)運算子而言。當它用於不可變物件時(如在a += 1或在s += 'qwertz'中),Python 將默默地建立一個新物件,並將該變數指向它。但是,當它用於可變物件時(如在l += [1,2,3]中),該變數指向的物件將被原地更改。雖然在大多數情況下,您不必瞭解這種不同的行為,但當多個變數指向同一個物件時,它與相關性。在我們的示例中,假設您設定p = sm = l,然後s += 'etc'l += [9,8,7]。這將改變s並保留p不受影響,但會改變兩者ml因為它們都指向同一個列表物件。Python 的內建id()函式,它返回給定變數名的唯一物件識別符號,可用於跟蹤幕後發生的事情。
通常,Python 的這種行為會導致函式中的混亂。作為說明,請考慮以下程式碼

def append_to_sequence (myseq):
    myseq += (9,9,9)
    return myseq

tuple1 = (1,2,3) # tuples are immutable
list1 = [1,2,3] # lists are mutable

tuple2 = append_to_sequence(tuple1)
list2 = append_to_sequence(list1)

print('tuple1 = ', tuple1) # outputs (1, 2, 3)
print('tuple2 = ', tuple2) # outputs (1, 2, 3, 9, 9, 9)
print('list1 = ', list1) # outputs [1, 2, 3, 9, 9, 9]
print('list2 = ', list2) # outputs [1, 2, 3, 9, 9, 9]

這將產生上述指示的(通常是意外的)輸出。myseqappend_to_sequence函式的區域性變數,但當該函式被呼叫時,myseq仍然將指向與我們傳入的變數(tl在我們示例中)相同的物件。如果該物件是不可變的(例如元組),則不會有任何問題。+= 運算子將導致建立一個新的元組,並且myseq將被設定為指向它。但是,如果我們傳入一個對可變物件的引用,則該物件將被原地操作(因此myseql在我們的示例中,最終將指向同一個列表物件)。

連結

建立定義型別的物件

[編輯 | 編輯原始碼]

文字整數可以透過三種方式輸入

  • 十進位制數可以直接輸入
  • 十六進位制數可以透過在前面新增 0x 或 0X 來輸入(0xff 是十六進位制 FF,或十進位制 255)
  • 八進位制文字的格式取決於 Python 的版本
  • Python 2.x:可以透過在前面新增零 (0) 來輸入八進位制數 (0732 是八進位制 732,或十進位制 474)
  • Python 3.x:可以透過在前面新增零,後跟字母 O (0o 或 0O) 來輸入八進位制數 (0o732 是八進位制 732,或十進位制 474)

浮點數可以直接輸入。

長整數可以透過直接輸入 (1234567891011121314151617181920 是一個長整數) 或透過在後面新增 L (0L 是一個長整數) 來輸入。涉及短整數溢位的計算會自動轉換為長整數。

複數可以透過新增一個實數和一個虛數來輸入,虛數可以透過在後面新增 j 來輸入(例如 10+5j 是一個複數。10j 也是一個複數)。請注意,單獨的 j 不構成一個數字。如果需要,請使用 1j。

字串可以是單引號或三引號字串。區別在於開始和結束分隔符,以及單引號字串不能跨越多行。單引號字串可以透過輸入單引號 (') 或雙引號 (") 後面跟著其匹配項來輸入。因此

'foo' works, and
"moo" works as well,
     but
'bar" does not work, and
"baz' does not work either.
"quux'' is right out.

三引號字串類似於單引號字串,但可以跨越多行。它們的開始和結束分隔符也必須匹配。它們用三個連續的單引號或雙引號輸入,因此

'''foo''' works, and
"""moo""" works as well,
     but
'"'bar'"' does not work, and
"""baz''' does not work either.
'"'quux"'" is right out.

元組在括號中輸入,條目之間用逗號隔開

(10, 'Mary had a little lamb')

此外,當不含糊時,可以省略括號

10, 'whose fleece was as white as snow'

請注意,單元素元組可以透過將條目用括號括起來並新增逗號來輸入,例如

('this is a singleton tuple',)

列表類似,但用方括號

['abc', 1,2,3]

字典透過用花括號將用冒號分隔的鍵/值對列表括起來,並用逗號將其他條目分隔開來,來建立

{ 'hello': 'world', 'weight': 'African or European?' }

這些複合型別中的任何一個都可以包含任何其他型別,深度不受限制

((((((((('bob',),['Mary', 'had', 'a', 'little', 'lamb']), { 'hello' : 'world' } ),),),),),),)

空物件

[編輯 | 編輯原始碼]

在 Python 中,類似於其他程式語言中的空指標,使用 None 來表示。None 不是空指標或空引用,而是一個實際存在的物件,並且只有一個例項。None 的用途之一是在函式的預設引數值中,詳情請參見 Python Programming/Functions#Default_Argument_Values。通常使用 is 而不是 == 來比較 None

測試 None 和賦值

if item is None:
  ...
  another = None

if not item is None:
  ...

if item is not None: # Also possible
  ...

在預設引數值中使用 None

def log(message, type = None):
  ...

PEP8 規定“與單例(如 None)的比較應該始終使用 is 或 is not,而不是相等運算子”。因此,“if item == None:” 是不可取的。類可以重新定義相等運算子(==),以便該類的例項等於 None。

你可以透過 dir(None) 或 id(None) 來驗證 None 是一個物件。

另請參見 Operators#Identity 章節。

連結

型別轉換

[edit | edit source]

Python 中型別轉換示例

v1 = int(2.7) # 2
v2 = int(-3.9) # -3
v3 = int("2") # 2
v4 = int("11", 16) # 17, base 16
v5 = long(2) # Python 2.x only, not Python 3.x
v6 = float(2) # 2.0
v7 = float("2.7") # 2.7
v8 = float("2.7E-2") # 0.027
v9 = float(False) # 0.0
vA = float(True) # 1.0
vB = str(4.5) # "4.5"
vC = str([1, 3, 5]) # "[1, 3, 5]"
vD = bool(0) # False; bool fn since Python 2.2.1
vE = bool(3) # True
vF = bool([]) # False - empty list
vG = bool([False]) # True - non-empty list
vH = bool({}) # False - empty dict; same for empty tuple
vI = bool("") # False - empty string
vJ = bool(" ") # True - non-empty string
vK = bool(None) # False
vL = bool(len) # True
vM = set([1, 2])
vN = set((1, 2)) # Converts any sequence, not just a list
vO = set("abc") # {'c', 'b', 'a'}
vP = set(b"abc") # {97, 98, 99}
vQ = list(vM)
vR = list({1: "a", 2: "b"}) # dict -> list of keys
vS = tuple(vQ)
vT = list("abc") # ['a', 'b', 'c']
print(v1, v2, v3, type(v1), type(v2), type(v3))

隱式型別轉換

int1 = 4
float1 = int1 + 2.1 # 4 converted to float
# str1 = "My int:" + int1 # Error: no implicit type conversion from int to string
str1 = "My int:" + str(int1)
int2 = 4 + True # 5: bool is implicitly converted to int
float2 = 4.5 + True # 5.5: True is converted to 1, which is converted to 1.0

關鍵詞:型別強制轉換。

連結

練習

[edit | edit source]
  1. 編寫一個程式,例項化一個物件,將 [1,2] 新增到該物件中,並返回結果。
    1. 找到一個物件,它返回相同長度的輸出(如果存在的話?)。
    2. 找到一個物件,它返回的輸出長度比初始長度大 2。
    3. 找到一個導致錯誤的物件。
  2. 找到兩種資料型別 X 和 Y,使得 X = X + Y 會導致錯誤,但 X += Y 不會。
華夏公益教科書