内置类型之真值测试、数字类型、布尔运算等(4) – Python语言(必读进阶学习教程)(参考资料)
以下部分描述了解释器中内置的标准类型。
主要的内置类型是数字,序列,映射,类,实例和异常。
一些集合类是可变的。添加,删除或重新安排其成员的方法,并且不返回特定项,从不返回集合实例本身None
。
一些操作由几种对象类型支持; 特别是,实际上所有对象都可以进行比较,测试真值,并转换为字符串(具有repr()
功能或略有不同的 str()
功能)。当函数写入对象时,隐式使用后一个print()
函数。
真值测试
任何对象都可以用于真值进行测试,用于在使用if
或 while
病症或如下面的布尔运算的操作数。
默认情况下,对象被视为true,除非其类定义 __bool__()
返回False
的__len__()
方法或返回零的方法(使用对象调用时)。[1] 以下是大多数被认为是错误的内置对象:
- 常量定义为false:
None
和False
。 - 任何数值类型的零:
0
,0.0
,0j
,Decimal(0)
,Fraction(0, 1)
- 空序列和集合:
''
,()
,[]
,{}
,set()
,range(0)
除非另有说明,否则具有布尔结果的操作和内置函数始终返回0
或返回False
false 1
或True
为true。(重要的例外:布尔运算or
并and
始终返回其中一个操作数。)
布尔运算– ,,and
or
not
这些是布尔运算,按升序排序:
手术 | 结果 | 笔记 |
---|---|---|
x or y |
如果x为假,那么y,否则为 x | (1) |
x and y |
如果x为假,则为x,否则为 y | (2) |
not x |
如果x为假,那么True ,否则False |
(3) |
笔记:
- 这是一个短路运算符,因此只有在第一个参数为false时才会计算第二个参数。
- 这是一个短路运算符,因此只有在第一个参数为真时它才会计算第二个参数。
not
优先级低于非布尔运算符,因此被解释为,并且是语法错误。not a == b
not (a == b)
a == not b
比较
Python中有八个比较操作。它们都具有相同的优先级(高于布尔操作的优先级)。比较可以任意链接; 例如,等同于,除了y仅被评估一次(但在两种情况下,当发现为假时,z根本不被评估)。x < y <= z
x < y and y <= z
x <y
该表总结了比较操作:
手术 | 含义 |
---|---|
< |
严格不到 |
<= |
小于等于 |
> |
严格大于 |
>= |
大于或等于 |
== |
等于 |
!= |
不平等 |
is |
对象身份 |
is not |
否定了对象的身份 |
除了不同的数字类型之外,不同类型的对象永远不会相等。此外,某些类型(例如,函数对象)仅支持简并比较概念,其中该类型的任何两个对象都是不相等的。的<
, <=
,>
和>=
运营商将提出一个TypeError
比较复杂的数字时异常另一个内置数字型,当对象是不同的类型,而且不能比拟的,或在其他情况下,没有定义排序的。
除非类定义__eq__()
方法,否则类的非相同实例通常会比较为不相等。
一个类的实例不能相对于同一类的其他实例,或其他类型的对象进行排序,除非类定义了足够的方法__lt__()
,__le__()
,__gt__()
,和__ge__()
(在一般情况下,__lt__()
并__eq__()
有足够的,如果你想要的传统含义比较运算符)。
is
和运营商的行为无法定制; 它们也可以应用于任何两个对象,并且永远不会引发异常。is not
具有相同优先级的语法两个操作,in
并且 ,是由类型支持迭代或实现方法。not in
__contains__()
数字类型– ,,int
float
complex
有三种不同的数字类型:整数,浮点数和复数。此外,布尔值是整数的子类型。整数具有无限的精度。浮点数通常double
在C中实现; 有关运行程序的机器的浮点数的精度和内部表示的信息,请参见sys.float_info
。复数具有实部和虚部,每个都是浮点数。要从复数z中提取这些部分,请使用z.real
和z.imag
。(标准库包括其他数字类型,fractions
其中包含有理数,以及decimal
保持具有用户可定义精度的浮点数。)
数字由数字文字或内置函数和运算符的结果创建。未修饰的整数文字(包括十六进制,八进制和二进制数)产生整数。包含小数点或指数符号的数字文字会产生浮点数。附加'j'
或'J'
数字文字会产生一个虚数(具有零实部的复数),您可以将其添加到整数或浮点数以获得具有实部和虚部的复数。
Python完全支持混合算术:当二进制算术运算符具有不同数值类型的操作数时,具有“较窄”类型的操作数被扩展为另一个的操作数,其中整数比浮点更窄,这比复数更窄。混合类型数量之间的比较使用相同的规则。[2]构造函数int()
,float()
和, complex()
可用于生成特定类型的数字。
所有数字类型(复杂除外)都支持以下操作,按升序优先级排序(所有数字操作的优先级都高于比较操作):
手术 | 结果 | 笔记 | 完整文档 |
---|---|---|---|
x + y |
x和y的总和 | ||
x - y |
x和y的差异 | ||
x * y |
x和y的乘积 | ||
x / y |
x和y的商 | ||
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) |
笔记:
-
也称为整数除法。结果值是整数,但结果的类型不一定是int。结果总是四舍五入向负无穷大:
1//2
是0
,(-1)//2
是-1
,1//(-2)
是-1
,和(-1)//(-2)
是0
。 -
不是复杂的数字。而是使用
abs()
适当的方式转换为浮点数。 -
从浮点到整数的转换可以像在C中那样舍入或截断; 查看功能
math.floor()
和math.ceil()
明确定义的转换。 -
float也接受字符串“nan”和“inf”,带有可选前缀“+”或“ – ”表示非数字(NaN)和正或负无穷大。
-
Python的定义和要,因为是编程语言常见。
pow(0, 0)
0 ** 0
1
-
接受的数字文字包括数字
0
到9
或任何Unicode当量(与代码点Nd
属性)。有关具有 Nd 属性的代码点的完整列表,请参阅 http://www.unicode.org/Public/10.0.0/ucd/extracted/DerivedNumericType.txt。
所有numbers.Real
类型(int
和float
)还包括以下操作:
手术 | 结果 |
---|---|
math.trunc(x) |
x截断为Integral |
round(x[, n]) |
x舍入为n位数,舍入为偶数的一半。如果省略n,则默认为0。 |
math.floor(x) |
最大的Integral <= x |
math.ceil(x) |
至少Integral > = x |
有关其他数字操作,请参阅math
和cmath
模块。
整数类型的按位运算
按位运算仅对整数有意义。计算按位运算的结果,就好像用无穷多个符号位的二进制补码进行计算一样。
二进制按位运算的优先级都低于数值运算,高于比较; 一元操作~
与其他一元数字操作具有相同的优先级(+
和-
)。
此表列出按升序排序的按位操作:
手术 | 结果 | 笔记 |
---|---|---|
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的位被反转 |
笔记:
- 负移位计数是非法的并导致
ValueError
提升。 - 左移n位相当于 没有溢出检查的乘法。
pow(2, n)
- 右移n位相当于没有溢出检查的除法。
pow(2, n)
- 在有限二进制补码表示(工作位宽或更大)中使用至少一个额外符号扩展位执行这些计算 足以得到与无限数量的符号位相同的结果。
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**k
abs(x)
k = 1 + int(log(abs(x),2))
x
x.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.
lengthto_bytes(
byteorder,
*,
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
字节顺序值。在签署参数确定补是否被用来表示整数。如果signed是
False
并且给出了一个负整数,OverflowError
则引发a。signed的默认值 是False
。版本3.2中的新功能。
- classmethod
int.
bytesfrom_bytes(
byteorder,
*,
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.
is_integer()
- 返回
True
如果浮子实例是有限的与积分值,并False
以其他方式:>>> >>> (-2.0).is_integer() True >>> (3.2).is_integer() False
两种方法支持十六进制字符串的转换。由于Python的浮点数在内部存储为二进制数,因此将浮点数转换为十进制字符串或从 十进制字符串转换通常会导致小的舍入错误。相反,十六进制字符串允许精确表示和指定浮点数。这在调试和数值工作时非常有用。
float.
hex()
- 将浮点数的表示形式返回为十六进制字符串。对于有限浮点数,此表示将始终包括前导
0x
和尾随p
和指数。
注意,这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'
哈希数值类型
对于数字x
和y
可能不同类型的,它是一个要求,只要(见 更多细节方法的文档)。为了便于实施和效率在各种的数字类型的(包括, ,和)Python的数字类型的散列是基于对于任何合理的数目来定义,因此,一个单一的数学函数将应用于的所有实例 和所有的有限的情况下,和中 和。本质上,此函数由固定素数的减少模数给出。Python 的值可以作为Python的属性使用 。hash(x) == hash(y)
x ==y
__hash__()
int
float
decimal.Decimal
fractions.Fraction
int
fractions.Fraction
float
decimal.Decimal
P
P
P
modulus
sys.hash_info
CPython实现细节:目前,使用的素数是在具有32位C 长度的机器上以及在具有64位C 长度的机器上。P = 2**31- 1
P = 2**61 - 1
以下是详细规则:
- 如果是非负有理数并且不能被整除,则定义为,其中给出模数的倒数。
x = m / n
n
P
hash(x)
m * invmod(n,P) % P
invmod(n, P)
n
P
- 如果是非负有理数并且可以被(但不是)整除,那么就没有逆模,并且上面的规则不适用; 在这种情况下,定义 为常量值。
x = m / n
n
P
m
n
P
hash(x)
sys.hash_info.inf
- 如果是负有理数定义 为。如果生成的哈希是,请将其替换为 。
x = m / n
hash(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.width
range(-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