Python 數值類型——《Python學習手冊》第 5 章學習筆記

數值類型基礎知識

在 Python 中,數字並不真的是隻是一種對象類型,而是一組相似類型的分類。完整的 Python 數值類型工具包括:整數和浮點對象複數對象小數:固定精度對象分數:有理數對象集合:帶有數值運算的集合體布爾值:真和假內置函數模塊:round、math、random 等表達式:無限制整數精度;位運算;十六進制、八進制和二進制格式第三方擴展:向量、庫、可視化、作圖等

數值字面量

Python 提供了整數(包括正整數、負整數和零)以及浮點數(帶有小數部分的數字)作爲其基本類型。

整數和浮點數字面量

整數寫成十進制數字的串。浮點數帶一個小數點,也可以加上一個科學技術標誌 e 或者 E。浮點數在標準 CPython 中採用 C 語言中的“雙精度”來實現,因此,其精度與用來構建 Python 解釋器的 C 編譯器所給定的精度一樣。

Python 2.X 中的整數:一般整數和長整數

Python 2.X 中有兩種整數類型:一般整數(通常 32 位)和長整數(無限精度),並且一個整數可以以 l 或 L 結尾,從而強制它轉換爲長整數。

Python 3.X 中的整數:單獨的一種類型

Python 3.X 中,一般整數和長整數類型合二爲一——只有整數這一種,它自動地支持 Python 2.X 中的長整數類型所擁有的無窮精度。因此,整數在程序中不再有末尾的 l 或 L 表示,並且整數也不再顯示這個字符。

十六進制、八進制和二進制字面量

整數可以編寫爲十進制(以 10 爲基數)、十六進制(以 16 爲基數)、八進制(以 8 爲基數)和二進制(以 2 爲基數)形式。十六進制數以 0x 爲 0X 開頭,後面接十六進制的數字 0-9 和 A-F。十六進制的數字編寫成大寫或小寫都可以。八進制數字面量以數字 0o 或 0O 開頭(數字 0 後面加小寫或大寫的字母“o”),後面跟數字 0-7 構成的數字串。Python 3.X 中的二進制字面量以 0b 或 0B 開頭,後面跟着二進制數字(0-1)。
要注意,所有這些字面量在程序代碼中都產生一個整數對象,它們僅僅是特定值的不同語法表示。內置函數 hex(I)、oct(I) 和 bin(I) 把一個整數轉換爲這 3 種進製表示的字符串,並且 int(str,base) 根據每個給定的進制把一個運行時字符串轉換爲一個整數。

複數

Python 的複數字面量寫成實部 + 虛部的寫法,這裏虛部是以 j 或 J 結尾。其中,虛部可以獨立於實部單獨存在。複數也可以通過內置函數 complex(real,imag) 來創建。

Python 表達式運算符

表達式的定義是:數字(或其他對象)與運算符相結合,並被 Python 在執行時計算爲一個值。
下表爲 Python 表達式運算符及程序,在該表中,運算符從上到下優先級逐漸增高,也就是說越下面的表達式“綁定得越緊”

運算符 描述
yield x 生成器函數 send 協議
lambda args: expression 創建匿名函數
x if y else z 三元選擇表達式(僅當 y 爲真時,x 纔會被計算)
x or y 邏輯或(僅當 x 爲假時,y 纔會被計算)
x and y 邏輯與(僅當 x 爲真時,y 纔會被計算)
not x 邏輯非
x in y, x not in y 成員關係(可迭代對象、集合)
x is y, x is not y 對象同一性測試
x < y, x <= y, x > y, x >= y 大小比較,集合的子集和超集
x == y, x != y 值等價性運算符
x | y 按位或、集合並集
x ^ y 按位異或、集合對稱差集
x & y 按位與、集合交集
x << y, x >> y 將 x 左移或右移 y 位
x + y 加法、拼接
x - y 減法、集合差集
x * y 乘法、重複
x % y 求餘數、格式化
x / y, x // y 真除法、向下取整除法
-x, +x 取負、取正
~x 按位非(取反碼)
x ** y 冪運算(指數)
x[i] 索引(序列、映射等)
x[i:j:k] 分片
x(...) 調用(函數、方法、類,其他可調用對象)
x.attr 屬性引用
(...) 元組、表達式、生成器表達式
[...] 列表、列表推導
{...} 字典、集合、集合與字典推導
  • 在 Python 2.X 中,值的不相等可以寫成 X != Y 或 X <> Y。在 Python 3.X 中,X <> Y 的形式被移除了。
  • 在 Python 2.X 中,一個反引號表達式 `X` 與 repr(X) 的作用相同,目的是轉換對象以顯示字符串。由於它不易理解,因此 Python 3.X 移除了這個表達式。
  • 在 Python 2.X 和 Python 3.X 中,X // Y 對應的向下取整除法表達式總是會把商的小數部分去掉。在 Python 3.X 中,X / Y 表達式會執行真除法(保留了商的小數部分),在 Python 2.X 中,X / Y 表達式會執行經典除法(截斷爲整數)。
  • [...] 語法同時用於列表字面量、列表推導表達式。列表推導表達式會執行隱式的循環,並把表達式的結果收集到一個新列表中。
  • (...) 語法用於元組和表達式分組,以及生成器表達式。生成器是一種能夠按需產生結果的列表推導,而不是一次性創建完整的結果列表。
  • {...} 語法用於字典字面量,並且在 Python 3.X 和 2.7 中可以表示集合字面量以及字典和集合推導。
  • yield 和 三元 if/else 表達式在 Python 2.5 之後的版本可用。如果 yield 不是單獨地位於一條賦值語句的右邊,需要使用圓括號。
  • 在 Python 2.X 中,比較混合類型的相對大小是允許的,這會把數字轉換爲一個普通類型,並且根據類型名稱來排序其他的混合類型;而在 Python 3.X 中,比較非數字的混合類型的相對大小是不允許的,並且會引發異常;而通過代理的排序也會引發異常。
  • 在 Python 3.X 中,字典的相對大小比較也不再支持(支持等價性測試);比較 sorted(aDict.items()) 是一種可能的替代。

混合類型向上轉換

在混合類型的表達式中,Python 首先將被操作的對象轉換成其中最複雜的操作數的類型,然後再對相同類型的操作數進行數學運算。在 Python 中,整數比浮點數簡單,浮點數比複數簡單。所有這些混合類型轉換僅適用於數值類型(例如一個整數和一個浮點數)的混合,這包括那些使用數字和比較運算符的表達式。

數字的實際應用

變量與基礎表達式

在 Python 中:

  • 變量在第一次賦值時被創建。
  • 變量在表達式中使用時,會被替換成它們的值。
  • 變量在表達式中使用之前,必須已被賦值。
  • 變量引用對象,而且從不需要事先聲明。

在 Python 中不需要提前聲明變量,但變量在使用之前必須至少被賦值一次。實際上,這意味着在進行累加計數器之前必須先將它們賦值爲 0;在列表尾部添加元素之前必須先初始化一個空列表。

數值的顯示格式

str 和 repr 顯示格式

str 和 repr 都會把任意對象轉換成對應的字符串表示:repr 會產生看起來像代碼的結果。str 轉換爲一種通常對用戶更加友好的格式。

>>> repr('spam')
"'spam'"
>>> str('spam')
'spam'

普通比較與鏈式比較

Python 允許將相對大小比較測試鏈接起來,形成如範圍測試的連續比較。例如,表達式(A < B < C)測試了 B 是否位於 A 和 C 直接,等同於布爾測試( A < B and B < C )。

>>> A = 2
>>> B = 4
>>> C = 6
>>> A < B < C
True
>>> A < B and B < C
True
>>> A < B > C
False
>>> A < B and B > C
False
>>> 1 == 2 < 3
False
>>> 1.1 + 2.2 == 3.3
False
>>> 1.1 + 2.2
3.3000000000000003
>>> int(1.1 + 2.2)
3
>>> int(3.3)
3
>>> int(1.1 + 2.2) == int(3.3)
True

除了鏈接,數值比較是基於相對大小的。可能浮點數不會總是按照預期的想法工作,這是由於浮點數因爲有限的比特位數,而不能精確地表示某些值。這是數值編程的一個基本問題,而不只是在 Python 中出現。

除法:經典除法、向下取整除法和真除法

除法的行爲在 Python 3.X 和 Python 2.X 中略有差異。

X / Y
經典除法和真除法。在 Python 2.X 或之前的版本中,這個操作對於整數會省去小數部分,對於浮點數會保持餘項(小數部分)。在 Python 3.X 中將會變成真除法,即無論任何類型,最終的浮點數結果都會保留小數部分

X // Y
向下取整除法。這是從 Python 2.2 開始新增的操作,在 Python 2.X 和 Python 3.X 中均能使用。這個操作不考慮操作對象的類型,總是會省略結果的小數部分,剩下的最小的能整除的整數部分。它的結果取決於操作數的類型。

概括地說,
在 Python 3.X 中,/ 現在總是執行真除法,不管操作數的類型,都返回包含任何小數部分的一個浮點數結果。// 執行向下取整除法,它截除掉餘數並針對整數操作數返回一個整數,如果有任何一個操作數是浮點數類型,則返回一個浮點數。
在 Python 2.X 中,/ 表示經典除法,如果兩個操作數都是整數的話,執行截斷的整數除法;否則,執行浮點除法。// 執行向下取整除法,並且像在 Python 3.X 中那樣工作,對於整數執行截斷除法,對於浮點數執行浮點除法。

[root@binguo ~]# python
Python 3.6.1 (default, Sep 19 2019, 17:19:47) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 10 / 4
2.5
>>> 10 / 4.0
2.5
>>> 10 // 4
2
>>> 10 // 4.0
2.0
>>> 10 / 4,10 / -4
(2.5, -2.5)
>>> 10 // 4,10 // -4
(2, -3)

十六進制、八進制和二進制:字面量與轉換

要記得的是,下面的這些字面量只是指定一個整數對象的值的一種替代方式。在 Python 3.X 和 Python 2.X 中編寫的如下字面量會產生具有上述 3 種進制數的常規整數。在內存中,同一個整數的值是相同的,它與我們爲了指定它而使用的底數無關

>>> 0o1,0o20,0o377
(1, 16, 255)
>>> 0x01,0x10,0xFF
(1, 16, 255)
>>> 0b1,0b10000,0b11111111
(1, 16, 255)

Python 默認用十進制值(以 10 爲底)顯示整數數值,也提供了能把整數轉換爲其他進制的數字字符串(以 Python 字面量的形式)。

>>> oct(64),hex(64),bin(64)
('0o100', '0x40', '0b1000000')

oct 函數將十進制數轉爲八進制數,hex 函數會將十進制轉換爲十六進制數,bin 函數會將十進制數轉換爲二進制。
反過來,內置函數 int 會將一個數字的字符串轉換爲一個整數,並通過可選的第二位參數來確定轉換後數字的進制。

>>> 64,0o100,0x40,0b1000000
(64, 64, 64, 64)
>>> int('64'),int('100',8),int('40',16),int('1000000',2)
(64, 64, 64, 64)

eval 函數,會把字符串作爲 Python 代碼來運行。因此,它也具有和 int 函數類似的功能,但運行的更慢。實際上 eval 函數會把字符串作爲程序的一個片段編譯運行,並且假設當前運行的字符串屬於一個可信的來源。因此要小心使用 eval 調用。

>>> eval('64'),eval('0o100'),eval('0x40'),eval('0b1000000')
(64, 64, 64, 64)

最後,也可以使用字符串格式化方法調用和表達式(它只返回數字,而不是 Python 的字面量字符串),將整數轉換爲指定底的字符串:

>>> '{0:o},{1:x},{2:b}'.format(64,64,64)
'100,40,1000000'
>>> '%o,%x,%x,%X' % (64,64,255,255)
'100,40,ff,FF'

按位操作

下面是實際中 Python 的按位表達式運算符中的一部分,能夠實現整數的按位移動及布爾運算:

>>> x = 1
>>> x << 2
4
>>> x | 2
3
>>> x & 1
1

在第一個表達式中,二進制數 1(以 2 爲底數,0001)左移了兩位,成爲二進制的 4(0100)。
第二個表達式實現了一個二進制“或”來組合位(0001|0010=0011)。
第三個表達式實現了一個二進制“和”來選擇共同的位(0001&0001=0001)。

在 Python 3.0 中,可以按照位字符串來編寫和查看數字。

>>> x = 0b0001
>>> x
1
>>> x << 2
4
>>> bin(x << 2)
'0b100'
>>> bin(x | 0b010)
'0b11'
>>> bin(x & 0b1)
'0b1'
>>> x = 0xFF
>>> x
255
>>> bin(x)
'0b11111111'
>>> bin(x ^ 0b10101010)
'0b1010101'
>>> int('01010101',2)
85
>>> hex(85)
'0x55'

Python 3.1 和 2.7 引入了一個新的整數方法 bit_length,它可以查詢以二進制表示一個數字的值時所需的位數。也可以通過內置函數 len,從 bin 字符串的長度減 2(代表字面量字符串開頭的“0b”),也可以得到同樣的結果。

>>> x = 99
>>> bin(x),x.bit_length(),len(bin(x))-2
('0b1100011', 7, 7)
>>> bin(256),(256).bit_length(),len(bin(256))-2
('0b100000000', 9, 9)

其他數值類型

Python 的核心數值類型:整數、浮點數和複數。這裏介紹一些 Python 自帶的更少見的數值類型。

小數類型

Python 2.4 中引入一種新的核心數據類型:小數對象。其正式名稱是 Decimal。從語法上來講,需要通過調用已導入模塊中的函數來創建小數,而不是通過運行字面量表達式來創建。從功能上講,小數對象很像浮點數,但它們有固定的位數和小數點。因此,小數是精度固定的浮點數
使用小數對象,可以得到一個只保留兩位小數位精度的浮點數。此外,可以定義如何省略和截斷額外的小數數字

小數基礎知識

首先,浮點數運算缺乏精確性,這是因爲用來存儲數值的空間有限。可以使用小數對象是的一些浮點數運算結果更加精確:

>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')

當在表達式中混合使用精度不同的小數時,Python 會自動轉換爲最高的小數位數。

>>> Decimal('0.1') + Decimal('0.10') + Decimal('0.1') - Decimal('0.3')
Decimal('0.00')

在 Python 2.7、3.1 及之後的版本中,也可以通過 decimal.Decimal.from_float(1.25) 的形式從一個浮點數對象創建小數對象,最新的版本允許直接創建。這一轉換是精確的,但有時會產生默認且龐大的小數位數。

>>> Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)
Decimal('2.775557561565156540423631668E-17')

設置全局小數精度

decimal 模塊中的其他一些工具可以用來設置所有小數數值的精度,安排錯誤處理等。

>>> import decimal
>>> decimal.Decimal(1)/decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
>>> decimal.getcontext().prec = 4
>>> decimal.Decimal(1)/decimal.Decimal(7)
Decimal('0.1429')
>>> decimal.Decimal(0.1) + decimal.Decimal(0.1) + decimal.Decimal(0.1) - decimal.Decimal(0.3)
Decimal('1.110E-17')

小數上下文管理器

在 Python 2.6 和 3.0 及之後的版本中,可以使用 with 上下文管理器語句來臨時重置小數精度。

>>> import decimal
>>> decimal.Decimal('1.00')/decimal.Decimal('3.00')
Decimal('0.3333333333333333333333333333')
>>> with decimal.localcontext() as ctx:
...     ctx.prec = 2
...     decimal.Decimal('1.00')/decimal.Decimal('3.00')
... 
Decimal('0.33')
>>> decimal.Decimal('1.00')/decimal.Decimal('3.00')
Decimal('0.3333333333333333333333333333')

分數類型

Python 2.6 和 3.0 首次引入了新的數值類型 Fraction(分數),它實現了一個有理數對象。本質上,它顯式地保持了一個分子和一個分母,從而避免了浮點數運算的某些不精確性和侷限性。

分數基礎知識

分數的使用方式和小數很像。

>>> from fractions import Fraction
>>> x = Fraction(1,3)
>>> y = Fraction(4,6)
>>> x
Fraction(1, 3)
>>> y
Fraction(2, 3)
>>> print(x,y)
1/3 2/3
>>> x + y
Fraction(1, 1)
>>> x - y
Fraction(-1, 3)
>>> x * y
Fraction(2, 9)
>>> Fraction('.25')
Fraction(1, 4)
>>> Fraction('1.25')
Fraction(5, 4)
>>> Fraction(1.25)
Fraction(5, 4)

分數和小數中的數值精度

對浮點數對象進行相同的運算,在內存中它們仍然是不準確的。

>>> a = 1/3.0
>>> b = 4/6.0
>>> a
0.3333333333333333
>>> b
0.6666666666666666
>>> a + b
1.0
>>> a - b
-0.3333333333333333
>>> a * b
0.2222222222222222

在下面的例子中,浮點數並不能準確地給出期望的答案 0,但分數和小數做到了。

>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
>>> from fractions import Fraction
>>> Fraction(1,10) + Fraction(1,10) + Fraction(1,10) - Fraction(3,10)
Fraction(0, 1)
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')

分數和小數都能提供比浮點數更直觀和準確的結果,它們分別通過使用有理數表示以及通過限制精度做到這點。

>>> 1 / 3
0.3333333333333333
>>> Fraction(1,3)
Fraction(1, 3)
>>> import decimal
>>> decimal.getcontext().prec = 2
>>> Decimal(1)/Decimal(3)
Decimal('0.33')

實際上,分數既保持了精確性,又自動簡化了結果。

>>> (1 / 3) + (6 / 12)
0.8333333333333333
>>> Fraction(6,12)
Fraction(1, 2)
>>> Fraction(6,12) + Fraction(1,3)
Fraction(5, 6)
>>> decimal.Decimal(str(1/3)) + decimal.Decimal(str(6/12))
Decimal('0.83')

分數轉換和混用類型

爲了支持分數的轉換,浮點數對象現在有一個方法,能夠產生它們的分子和分母比,分數有一個 from_float 方法,並且 float 函數可以接受一個 Fraction 對象作爲參數。

>>> (2.5).as_integer_ratio()
(5, 2)
>>> f = 2.5
>>> z = Fraction(\*f.as_integer_ratio())
>>> z
Fraction(5, 2)
>>> x = Fraction(1,3)
>>> x
Fraction(1, 3)
>>> x +z
Fraction(17, 6)
>>> float(x)
0.3333333333333333
>>> float(z)
2.5
>>> float(x+z)
2.8333333333333335
>>> 17/6
2.8333333333333335
>>> Fraction.from_float(1.75)
Fraction(7, 4)
>>> Fraction(\*(1.75).as_integer_ratio())
Fraction(7, 4)

集合

Python 2.4 引入了集合(set),這是唯一的、不可變的對象的一個無序集合體(collection),這些對象支持與數學集合理論對應的操作。按照定義,一個元素在集合中只能出現一次,不管它被添加了多少次。

因爲集合是其他對象的集合體,因此它具有列表和字典這樣的對象的某些共同行爲。例如,集合是可迭代對象,可以按需增長或縮短,並且可以包含多種對象類型。一個集合的行爲很像一個有鍵無值的字典,不過集合還支持更多的操作。

然而,由於集合是無序的,而且不會把鍵映射到值,因此它們既不是序列也不是映射類型;它們是自成一體的類型。

集合基礎知識

要創建一個集合對象,可以向內置的 set 函數傳入一個序列或其他可迭代對象:

>>> x = set('abcde')
>>> y = set('bdxyz')
>>> x
{'b', 'd', 'c', 'a', 'e'}
>>> y
{'z', 'd', 'x', 'y', 'b'}

要注意集合並不包含位置順序——它們的順序是任意的,且可能隨 Python 版本而變化。

集合通過表達式運算符支持一般的數學集合運算。要注意,不能對諸如字符串、列表和元組的一般序列使用下面的運算。

>>> x - y
{'a', 'c', 'e'}
>>> x | y
{'e', 'a', 'y', 'b', 'z', 'c', 'x', 'd'}
>>> x & y
{'b', 'd'}
>>> x ^ y
{'e', 'a', 'y', 'z', 'c', 'x'}
>>> x > y,x < y
(False, False)

該規則很明顯的一個例外就是集合成員測試 in。in 表達式也定義爲可以在全部其他集合體類型上工作,其作用也是進行成員測試。

>>> 'e' in x
True
>>> 'e' in 'Camelot', 22 in [11,22,33]
(True, True)

集合對象還提供了一些方法來支持集合的修改:add 方法插入一個項目,update 方法在原位置求並集,remove 根據值刪除一個元素。並且作爲可迭代的容器,集合也可以用於 len,for 循環和列表推導這樣的操作。然而,由於集合是無序的,所以不支持像索引和分片這樣的操作。

>>> z = x.intersection(y)
>>> z
{'b', 'd'}
>>> z.add('SPAM')
>>> z
{'b', 'SPAM', 'd'}
>>> z.update(set(['x','Y']))
>>> z
{'SPAM', 'b', 'x', 'Y', 'd'}
>>> z.remove('b')
>>> z
{'SPAM', 'x', 'Y', 'd'}
>>> for item in set('abc'): print(item*3)
... 
aaa
ccc
bbb
>>> len(z)
4

注意,儘管前面介紹的集合表達式通常需要兩個集合,但它們基於方法的對應形式往往可以對任何可迭代類型有效。

>>> S = set([1,2,3])
>>> S | set([3,4])
{1, 2, 3, 4}
>>> S | [3,4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'set' and 'list'
>>> S.union([3,4])
{1, 2, 3, 4}
>>> S.intersection((1,3,5))
{1, 3}
>>> S.issubset(range(-5,5))
True

不可變性限制與凍結集合

集合有一個限制要記住:集合只能包含不可變的(可哈希化的)對象類型。因此,列表和字典不能嵌入集合中,元組是可以嵌入集合的

>>> S
{1, 2, 3}
>>> S.add([1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> S.add({'a':1})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> S.add((1,2,3))
>>> S
{1, 2, 3, (1, 2, 3)}
>>> S | {(1,2,3),(4,5,6)}
{1, 2, 3, (1, 2, 3), (4, 5, 6)}
>>> S
{1, 2, 3, (1, 2, 3)}
>>> (1,2,3) in S
True
>>> (1,4,3) in S
False
>>> (1,2) in S
False

集合可以包含模塊、類型對象等。集合本身也是可變的,因此,不能直接嵌入其他集合中;如果要在另一個集合中存儲一個集合,可以像調用 set 一樣調用內置函數 frozenset,但 frozenset 會創建一個不可變的集合,該集合不可修改,並且可以嵌套到其他集合中。

集合推導

集合推導表達式類似於列表推導的形式。集合推導會運行一個循環並在每次迭代時收集一個表達式的結果,通過一個循環變量來訪問當前的迭代值以用於集合表達式中。其結果就是通過運行代碼創建了一個新的集合,它具備所有一般的集合行爲。

>>> {x ** 2 for x in [1,2,3,4]}
{16, 1, 4, 9}
>>> {x for x in 'spam'}
{'a', 's', 'm', 'p'}
>>> {c * 4 for c in 'spam'}
{'pppp', 'ssss', 'aaaa', 'mmmm'}
>>> S = {c * 4 for c in 'spam'}
>>> S | {'mmmm','xxxx'}
{'xxxx', 'pppp', 'mmmm', 'ssss', 'aaaa'}
>>> S & {'mmmm','xxxx'}
{'mmmm'}

集合使用實例

由於項在集合中只能存儲一次,因此集合可以用於過濾其他集合體的重複項,注意,元素可能會在該過程中重新排序(因爲集合通常是無序的)。

>>> L = [1,2,1,3,2,4,5]
>>> set(L)
{1, 2, 3, 4, 5}
>>> L = list(set(L))
>>> L
[1, 2, 3, 4, 5]
>>> list(set(['yy','cc','aa','xx','dd','aa']))
['yy', 'xx', 'aa', 'dd', 'cc']

集合也可以用於提取列表、字符串以及其他可迭代對象中的差異,只需轉換爲集合從而獲得差異。

>>> set([1,3,5,7]) - set([1,2,4,5,6])
{3, 7}
>>> set('abcdefg') - set('abdghij')
{'e', 'c', 'f'}
>>> set('spam') - set(['h','a','m'])
{'s', 'p'}
>>> set(dir(bytes)) - set(dir(bytearray))
{'__getnewargs__'}
>>> set(dir(bytearray)) - set(dir(bytes))
{'append', '__imul__', 'extend', 'remove', 'copy', 'clear', 'insert', 'pop', '__delitem__', '__iadd__', '__setitem__', '__alloc__', 'reverse'}

也可以通過轉換成集合,藉助集合進行順序無關的等價性測試。這是因爲順序在集合中並不重要。兩個集合相等當且僅當兩個集合中的每一個元素都被另一個集合所包含,也就是說,撇開順序,每一個集合都是另一個集合的子集。

>>> L1,L2=[1,3,5,2,4],[2,5,3,4,1]
>>> L1 == L2
False
>>> set(L1)==set(L2)
True
>>> sorted(L1)==sorted(L2)
True

布爾型

可以這樣認爲,Python 的布爾類型(bool)本質上是數值的,因爲它包含兩個值 True 和 False,而且就是整數 1 和 0 的定製版,只不過打印時有所不同。更正式的說,Python 有一個名爲 bool 的顯式布爾數據類型,帶有 True 和 False 作爲可用且預賦值的內置名稱。在內部,名稱 True 和 False 是 bool 的實例,而 bool 實際上是內置整數類型 int 的子類(從面向對象的角度來看)。

>>> type(True)
<class 'bool'>
>>> isinstance(True,int)
True
>>> True == 1
True
>>> True is 1
False
>>> True or False
True
>>> True + 4
5
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章