You are here:  Home » Python » 内置类型之真值测试、数字类型、布尔运算等(4)Python语言(必读进阶学习教程)(参考资料)

以下部分描述了解释器中内置的标准类型。

主要的内置类型是数字,序列,映射,类,实例和异常。

一些集合类是可变的。添加,删除或重新安排其成员的方法,并且不返回特定项,从不返回集合实例本身None

一些操作由几种对象类型支持; 特别是,实际上所有对象都可以进行比较,测试真值,并转换为字符串(具有repr()功能或略有不同的 str()功能)。当函数写入对象时,隐式使用后一个print()函数。

 

真值测试

任何对象都可以用于真值进行测试,用于在使用if或 while病症或如下面的布尔运算的操作数。

默认情况下,对象被视为true,除非其类定义 __bool__()返回False__len__()方法或返回零的方法(使用对象调用时)。[1] 以下是大多数被认为是错误的内置对象:

  • 常量定义为false:NoneFalse
  • 任何数值类型的零:00.00jDecimal(0), Fraction(0, 1)
  • 空序列和集合:''()[]{}set(), range(0)

除非另有说明,否则具有布尔结果的操作和内置函数始终返回0 或返回Falsefalse 1True为true。(重要的例外:布尔运算orand始终返回其中一个操作数。)

 

布尔运算- ,,and ornot

这些是布尔运算,按升序排序:

手术 结果 笔记
x or y 如果x为假,那么y,否则为 x (1)
x and y 如果x为假,则为x,否则为 y (2)
not x 如果x为假,那么True,否则False (3)

笔记:

  1. 这是一个短路运算符,因此只有在第一个参数为false时才会计算第二个参数。
  2. 这是一个短路运算符,因此只有在第一个参数为真时它才会计算第二个参数。
  3. not优先级低于非布尔运算符,因此被解释为,并且是语法错误。not a == bnot (a == b)a == not b

 

比较

Python中有八个比较操作。它们都具有相同的优先级(高于布尔操作的优先级)。比较可以任意链接; 例如,等同于,除了y仅被评估一次(但在两种情况下,当发现为假时,z根本不被评估)。x < y <= zx < y and y <= zx <y

该表总结了比较操作:

手术 含义
< 严格不到
<= 小于等于
> 严格大于
>= 大于或等于
== 等于
!= 不平等
is 对象身份
is not 否定了对象的身份

除了不同的数字类型之外,不同类型的对象永远不会相等。此外,某些类型(例如,函数对象)仅支持简并比较概念,其中该类型的任何两个对象都是不相等的。的<, <=>>=运营商将提出一个TypeError比较复杂的数字时异常另一个内置数字型,当对象是不同的类型,而且不能比拟的,或在其他情况下,没有定义排序的。

除非类定义__eq__()方法,否则类的非相同实例通常会比较为不相等。

一个类的实例不能相对于同一类的其他实例,或其他类型的对象进行排序,除非类定义了足够的方法__lt__()__le__()__gt__(),和__ge__()(在一般情况下,__lt__()__eq__()有足够的,如果你想要的传统含义比较运算符)。

is和运营商的行为无法定制; 它们也可以应用于任何两个对象,并且永远不会引发异常。is not

具有相同优先级的语法两个操作,in并且 ,是由类型支持迭代或实现方法。not in__contains__()

 

数字类型- ,,int floatcomplex

有三种不同的数字类型:整数浮点数复数。此外,布尔值是整数的子类型。整数具有无限的精度。浮点数通常double在C中实现; 有关运行程序的机器的浮点数的精度和内部表示的信息,请参见sys.float_info。复数具有实部和虚部,每个都是浮点数。要从复数z中提取这些部分,请使用z.realz.imag。(标准库包括其他数字类型,fractions其中包含有理数,以及decimal 保持具有用户可定义精度的浮点数。)

数字由数字文字或内置函数和运算符的结果创建。未修饰的整数文字(包括十六进制,八进制和二进制数)产生整数。包含小数点或指数符号的数字文字会产生浮点数。附加'j''J'数字文字会产生一个虚数(具有零实部的复数),您可以将其添加到整数或浮点数以获得具有实部和虚部的复数。

Python完全支持混合算术:当二进制算术运算符具有不同数值类型的操作数时,具有“较窄”类型的操作数被扩展为另一个的操作数,其中整数比浮点更窄,这比复数更窄。混合类型数量之间的比较使用相同的规则。[2]构造函数int()float()和, complex()可用于生成特定类型的数字。

所有数字类型(复杂除外)都支持以下操作,按升序优先级排序(所有数字操作的优先级都高于比较操作):

手术 结果 笔记 完整文档
x + y xy的总和
x - y xy的差异
x * y xy的乘积
x / y xy的
x // y x和 y的平均商 (1)
x % y 余下的 x / y (2)
-x x否定了
+x x不变
abs(x) x的绝对值或大小 abs()
int(x) x转换为整数 (3)(6) int()
float(x) x转换为浮点数 (4)(6) float()
complex(re, im) 一个带有实部re的复数 ,虚部im。 默认为零。 (6) complex()
c.conjugate() 复数c的共轭物
divmod(x, y) 这对 (x // y, x % y) (2) divmod()
pow(x, y) x到幂y (5) pow()
x ** y x到幂y (5)

笔记:

  1. 也称为整数除法。结果值是整数,但结果的类型不一定是int。结果总是四舍五入向负无穷大:1//20(-1)//2是 -11//(-2)-1,和(-1)//(-2)0

  2. 不是复杂的数字。而是使用abs()适当的方式转换为浮点数。

  3. 从浮点到整数的转换可以像在C中那样舍入或截断; 查看功能math.floor()math.ceil()明确定义的转换。

  4. float也接受字符串“nan”和“inf”,带有可选前缀“+”或“ – ”表示非数字(NaN)和正或负无穷大。

  5. Python的定义和要,因为是编程语言常见。pow(0, 0)0 ** 01

  6. 接受的数字文字包括数字09或任何Unicode当量(与代码点Nd属性)。

    有关 具有该属性的代码点的完整列表,请参见http://www.unicode.org/Public/10.0.0/ucd/extracted/DerivedNumericType.txtNd

所有numbers.Real类型(intfloat)还包括以下操作:

手术 结果
math.trunc(x) x截断为Integral
round(x[, n]) x舍入为n位数,舍入为偶数的一半。如果省略n,则默认为0。
math.floor(x) 最大的Integral <= x
math.ceil(x) 至少Integral> = x

有关其他数字操作,请参阅mathcmath 模块。

 

整数类型按位运算

按位运算仅对整数有意义。计算按位运算的结果,就好像用无穷多个符号位的二进制补码进行计算一样。

二进制按位运算的优先级都低于数值运算,高于比较; 一元操作~与其他一元数字操作具有相同的优先级(+-)。

此表列出按升序排序的按位操作:

手术 结果 笔记
x | y 按位X和 ÿ (4)
x ^ y 按位异或的 Xÿ (4)
x & y 按位X和 ÿ (4)
x << n x向左移位n (1)(2)
x >> n x右移n (1)(3)
~x x的位被反转

笔记:

  1. 负移位计数是非法的并导致ValueError提升。
  2. 左移n位相当于 没有溢出检查的乘法。pow(2, n)
  3. 右移n位相当于没有溢出检查的除法。pow(2, n)
  4. 在有限二进制补码表示(工作位宽或更大)中使用至少一个额外符号扩展位执行这些计算 足以得到与无限数量的符号位相同的结果。1 + max(x.bit_length(), y.bit_length())

整数类型的其他方法

int类型实现抽象基类。此外,它还提供了一些方法:numbers.Integral

int.bit_length()

 

返回表示二进制整数所需的位数,不包括符号和前导零:

>>>
>>> n = -37
>>> bin(n)
'-0b100101'
>>> n.bit_length()
6

 

更确切地说,如果x不为零,则x.bit_length()是唯一的正整数k这样。等价地,当小到足以具有正确的圆对数时,那么。如果为零,则返回。2**(k-1) <= abs(x) < 2**kabs(x)k = 1 + int(log(abs(x),2))xx.bit_length()0

相当于:

def bit_length(self):
    s = bin(self)       # binary representation:  bin(-37) --> '-0b100101'
    s = s.lstrip('-0b') # remove leading zeros and minus sign
    return len(s)       # len('100101') --> 6

 

3.1版中的新功能。
int.to_byteslengthbyteorder*signed = False 
返回表示整数的字节数组。

>>> (1024).to_bytes(2, byteorder='big') 
b'\x04\x00' 
>>> (1024).to_bytes(10, byteorder='big') 
b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' 
>>> (-1024).to_bytes(10, byteorder='big', signed=True) 
b'\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00' 
>>> x = 1000 
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little') 
b'\xe8\x03'

 

整数用长度字节表示。OverflowError 如果整数不能用给定的字节数表示,则引发An 。

字节顺序参数确定用于表示整数的字节顺序。如果字节顺序"big",最显著字节在字节数组的开始。如果字节顺序"little",最显著字节在字节数组的末尾。要请求主机系统的本机字节顺序,请使用sys.byteorder字节顺序值。

签署参数确定补是否被用来表示整数。如果signedFalse并且给出了一个负整数,OverflowError则引发a。signed的默认值 是False

版本3.2中的新功能。

classmethod int.from_bytesbytesbyteorder*signed = False 
返回给定的字节数组表示的整数。

>>> int.from_bytes(b'\x00\x10', byteorder='big')
16 
>>> int.from_bytes(b'\x00\x10', byteorder='little') 
4096 
>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=True) 
-1024 
>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=False) 
64512 
>>> int.from_bytes([255, 0, 0], byteorder='big') 
16711680

 

参数bytes必须是类字节对象或可迭代生成字节。

字节顺序参数确定用于表示整数的字节顺序。如果字节顺序"big",最显著字节在字节数组的开始。如果字节顺序"little",最显著字节在字节数组的末尾。要请求主机系统的本机字节顺序,请使用sys.byteorder字节顺序值。

签署参数指示补是否被用来表示整数。

版本3.2中的新功能。

Float上的其他方法

float类型实现抽象基类。float还有以下附加方法。numbers.Real

float.as_integer_ratio
返回一对整数,其比率与原始浮点数完全相等,并带有正分母。提高 OverflowError无限和ValueErrorNaNs。
float.is_integer
返回True如果浮子实例是有限的与积分值,并False以其他方式:

>>>
>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False

 

两种方法支持十六进制字符串的转换。由于Python的浮点数在内部存储为二进制数,因此将浮点数转换为十进制字符串或从 十进制字符串转换通常会导致小的舍入错误。相反,十六进制字符串允许精确表示和指定浮点数。这在调试和数值工作时非常有用。

float.hex
将浮点数的表示形式返回为十六进制字符串。对于有限浮点数,此表示将始终包括前导0x和尾随p和指数。
classmethod float.fromhex
返回由十六进制字符串s表示的float的类方法。字符串s可以具有前导和尾随空格。

注意,这float.hex()是一个实例方法, float.fromhex()而是一个类方法。

十六进制字符串采用以下形式:

[sign] ['0x'] integer ['.' fraction] ['p' exponent]

其中,可选的sign由5任一+-integer 和fraction是十六进制数字串,以及exponent 是具有任选的前导符号十进制整数。大小写并不重要,并且整数或小数必须至少有一个十六进制数字。此语法类似于C99标准的6.4.4.2节中指定的语法,也类似于Java 1.5及更高版本中使用的语法。特别是,输出 float.hex()可用作C或Java代码中的十六进制浮点文字,并且由C的%a格式字符或Java 生成的十六进制字符串Double.toHexString被接受float.fromhex()

注意,指数是用十进制而不是十六进制写的,并且它给出2的幂乘以系数。例如,十六进制字符串0x3.a7p10表示浮点数,或 :

(3 + 10./16 + 7./16**2) * 2.0**103740.0
>>>
>>> float.fromhex('0x3.a7p10')
3740.0

 

应用反向转换以3740.0提供表示相同数字的不同十六进制字符串:

>>>
>>> float.hex(3740.0)
'0x1.d380000000000p+11'

 

 

哈希数值类型

对于数字xy可能不同类型的,它是一个要求,只要(见 更多细节方法的文档)。为了便于实施和效率在各种的数字类型的(包括, ,和)Python的数字类型的散列是基于对于任何合理的数目来定义,因此,一个单一的数学函数将应用于的所有实例 和所有的有限的情况下,和中 和。本质上,此函数由固定素数的减少模数给出。Python 的值可以作为Python的属性使用 。hash(x) == hash(y)x ==y__hash__()intfloatdecimal.Decimalfractions.Fractionintfractions.Fractionfloatdecimal.DecimalPPPmodulussys.hash_info

CPython实现细节:目前,使用的素数是在具有32位C 长度的机器上以及在具有64位C 长度的机器上。P = 2**31- 1P = 2**61 - 1

以下是详细规则:

  • 如果是非负有理数并且不能被整除,则定义为,其中给出模数的倒数。x = m / nnPhash(x)m * invmod(n,P) % Pinvmod(n, P)nP
  • 如果是非负有理数并且可以被(但不是)整除,那么就没有逆模,并且上面的规则不适用; 在这种情况下,定义 为常量值。x = m / nnPmnPhash(x)sys.hash_info.inf
  • 如果是负有理数定义 为。如果生成的哈希是,请将其替换为 。x = m / nhash(x)-hash(-x)-1-2
  • 特定值sys.hash_info.inf-sys.hash_info.inf 并sys.hash_info.nan用作正无穷大,负无穷大或分别为nans的散列值。(所有可清洗的nans都具有相同的哈希值。)
  • 对于一个complex数字z,实部和虚部的哈希值通过计算,减少的模数组合, 以便它位于其中 。再次,如果结果是,它被替换为。hash(z.real) + sys.hash_info.imag *hash(z.imag)2**sys.hash_info.widthrange(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width -1))-1-2

为了澄清上述规则,这里有一些示例Python代码,相当于内置哈希,用于计算有理数的哈希float,或complex

import sys, math 
def hash_fraction(m, n): 
"""Compute the hash of a rational number m / n. Assumes m and n are integers, with n positive. Equivalent to hash(fractions.Fraction(m, n)). """ 
    P = sys.hash_info.modulus 
    # Remove common factors of P. (Unnecessary if m and n already coprime.) 
    while m % P == n % P == 0: 
        m, n = m // P, n // P 
    if n % P == 0: 
        hash_value = sys.hash_info.inf 
    else: 
        # Fermat's Little Theorem: pow(n, P-1, P) is 1, so 
        # pow(n, P-2, P) gives the inverse of n modulo P. 
        hash_value = (abs(m) % P) * pow(n, P - 2, P) % P 
    if m < 0: 
        hash_value = -hash_value 
    if hash_value == -1: 
        hash_value = -2 
    return hash_value 

def hash_float(x): 
    """Compute the hash of a float x.""" 
    if math.isnan(x): 
        return sys.hash_info.nan 
    elif math.isinf(x): 
        return sys.hash_info.inf if x > 0 else -sys.hash_info.inf 
    else: 
        return hash_fraction(*x.as_integer_ratio()) 

def hash_complex(z): 
    """Compute the hash of a complex number z.""" 
    hash_value = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag) 
    # do a signed reduction modulo 2**sys.hash_info.width 
    M = 2**(sys.hash_info.width - 1) 
    hash_value = (hash_value & (M - 1)) - (hash_value & M) 
    if hash_value == -1: 
        hash_value = -2 
    return hash_value