您好,登錄后才能下訂單哦!
在 Python 中,數字并不真的是只是一種對象類型,而是一組相似類型的分類。完整的 Python 數值類型工具包括:整數和浮點對象;復數對象;小數:固定精度對象;分數:有理數對象;集合:帶有數值運算的集合體;布爾值:真和假;內置函數模塊:round、math、random 等;表達式:無限制整數精度;位運算;十六進制、八進制和二進制格式;第三方擴展:向量、庫、可視化、作圖等。
Python 提供了整數(包括正整數、負整數和零)以及浮點數(帶有小數部分的數字)作為其基本類型。
整數寫成十進制數字的串。浮點數帶一個小數點,也可以加上一個科學技術標志 e 或者 E。浮點數在標準 CPython 中采用 C 語言中的“雙精度”來實現,因此,其精度與用來構建 Python 解釋器的 C 編譯器所給定的精度一樣。
Python 2.X 中有兩種整數類型:一般整數(通常 32 位)和長整數(無限精度),并且一個整數可以以 l 或 L 結尾,從而強制它轉換為長整數。
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 表達式運算符及程序,在該表中,運算符從上到下優先級逐漸增高,也就是說越下面的表達式“綁定得越緊”。
運算符 | 描述 |
---|---|
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 首先將被操作的對象轉換成其中最復雜的操作數的類型,然后再對相同類型的操作數進行數學運算。在 Python 中,整數比浮點數簡單,浮點數比復數簡單。所有這些混合類型轉換僅適用于數值類型(例如一個整數和一個浮點數)的混合,這包括那些使用數字和比較運算符的表達式。
在 Python 中:
在 Python 中不需要提前聲明變量,但變量在使用之前必須至少被賦值一次。實際上,這意味著在進行累加計數器之前必須先將它們賦值為 0;在列表尾部添加元素之前必須先初始化一個空列表。
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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。