Skip to main content

4. 内置类型

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

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

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

一些操作由几个对象类型支持;实际上所有对象都可以进行比较,测试真值,并转换为字符串(使用 repr() 函数或稍微不同的 str() 函数)。当通过 print() 函数写入对象时,后者函数被隐式地使用。

4.1. 真值检验

任何对象都可以被测试真值,用于 ifwhile 条件或作为下面的布尔运算的操作数。以下值被视为false:

  • None

  • False

  • 任何数字类型的零,例如,00.00j

  • 任何空序列,例如,''()[]

  • 任何空映射,例如,{}

  • 用户定义的类的实例,如果该类定义了 __bool__()__len__() 方法,那么该方法返回整数零或 boolFalse[1]

所有其他值被认为是真的 - 所以许多类型的对象总是true。

除非另有说明,具有布尔结果的操作和内置函数始终将 0False 返回false,将 1True 返回true。 (重要的例外:布尔运算 orand 总是返回它们的操作数之一。)

4.2. 布尔运算— andornot

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

操作

结果

笔记

x or y

如果 x 为假,则 y,否则为 x

(1)

x and y

如果 x 为假,则 x,否则为 y

(2)

not x

如果 x 为假,则 True,否则为 False

(3)

笔记:

  1. 这是一个短路运算符,因此它只评估第二个参数,如果第一个是 False

  2. 这是一个短路运算符,因此它只评估第二个参数,如果第一个是 True

  3. not 具有比非布尔运算符更低的优先级,因此 not a == b 被解释为 not (a == b),并且 a == not b 是语法错误。

4.3. 比较

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

此表总结了比较操作:

操作

含义

<

严格小于

<=

小于或等于

>

严格大于

>=

大于或等于

==

等于

!=

不平等

is

对象标识

is not

否定对象身份

不同类型的对象,除了不同的数字类型,从不比较相等。此外,一些类型(例如,函数对象)仅支持比较的退化概念,其中该类型的任何两个对象是不相等的。当对象具有不同类型的无法比较的对象时,或者在没有定义的顺序的其他情况下,<<=>>= 运算符会在将复数与另一个内置数字类型进行比较时引发 TypeError 异常。

一个类的不相同实例通常比较为不等号,除非该类定义了 __eq__() 方法。

类的实例不能相对于同一类或其他类型的对象的其他实例排序,除非该类定义足够的方法 __lt__()__le__()__gt__()__ge__() (一般来说,__lt__()__eq__() 是足够的,如果你想要比较运算符的常规含义)。

isis not 操作员的行为不能定制;也可以应用于任何两个对象,从不引发异常。

具有相同句法优先级的两个操作 innot in 仅由序列类型支持(如下所示)。

4.4. 数字类型— intfloatcomplex

有三种不同的数值类型:integersfloating point numberscomplex numbers。此外,布尔是整数的子类型。整数具有无限精度。浮点数通常使用C中的 double 来实现;有关您的程序运行的机器的浮点数的精度和内部表示的信息在 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

xy 的商

(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 的复数,虚部 imim 默认为零。

(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 ** 0 定义为 1,这在编程语言中是常见的。

  6. 接受的数字文字包括数字 09 或任何Unicode等效(具有 Nd 属性的代码点)。

    有关具有 Nd 属性的代码点的完整列表,请参阅 http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedNumericType.txt

所有 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 模块。

4.4.1. 整数类型的按位操作

按位操作只对整数有意义。负数被视为其2的补码值(假设有足够的位,以便在操作期间不发生溢出)。

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

此表列出按升序排列的按位运算:

操作

结果

笔记

x | y

xy 的按位 or

 

x ^ y

xy 的按位 exclusive or

 

x & y

xy 的按位 and

 

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.4.2. 整数类型的其他方法

int类型实现 numbers.Integral abstract base class。此外,它还提供了几个方法:

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.to_bytes(length, 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'

整数用 length 字节表示。如果整数不能用给定数量的字节表示,则产生 OverflowError

byteorder 参数确定用于表示整数的字节顺序。如果 byteorder"big",则最高有效字节位于字节数组的开头。如果 byteorder"little",则最高有效字节位于字节数组的末尾。要请求主机系统的本机字节顺序,请使用 sys.byteorder 作为字节顺序值。

signed 参数确定是否使用二进制补码表示整数。如果 signedFalse 并且给出了负整数,则引发 OverflowErrorsigned 的默认值为 False

3.2 新版功能.

classmethod int.from_bytes(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 必须是 bytes-like object 或可迭代的产生字节。

byteorder 参数确定用于表示整数的字节顺序。如果 byteorder"big",则最高有效字节位于字节数组的开头。如果 byteorder"little",则最高有效字节位于字节数组的末尾。要请求主机系统的本机字节顺序,请使用 sys.byteorder 作为字节顺序值。

signed 参数指示二进制补码是否用于表示整数。

3.2 新版功能.

4.4.3. 浮法的附加方法

float类型实现 numbers.Real abstract base class。 float还有以下附加方法。

float.as_integer_ratio()

返回一对整数,其比例与原始浮点数完全相等,并使用正分母。提高 OverflowError 对无穷大和 ValueError 对NaNs。

float.is_integer()

如果float实例是有限整数值,则返回 True,否则返回 False:

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

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

float.hex()

将浮点数的表示形式返回为十六进制字符串。对于有限浮点数,此表示将始终包括前导 0x 和后沿 p 和指数。

classmethod float.fromhex(s)

类方法返回由十六进制字符串 s 表示的float。字符串 s 可以有前导和尾随空格。

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

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

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

其中可选的 sign 可以由 +-integerfraction 是十六进制数字的串,并且 exponent 是具有可选的前导符号的十进制整数。大小写不重要,并且在整数或分数中必须至少有一个十六进制数字。此语法与C99标准的第6.4.4.2节中指定的语法类似,也与Java 1.5以后使用的语法类似。特别地,float.hex() 的输出可用作C或Java代码中的十六进制浮点文本,并且由AA的 %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'

4.4.4. 数值类型的哈希

对于数字 xy,可能不同类型,它是一个要求,hash(x) == hash(y) 每当 x == y (更多细节参见 __hash__() 方法文档)。为了便于在各种数字类型(包括 intfloatdecimal.Decimalfractions.Fraction)中的实现和效率,Python对数值类型的哈希是基于为任何有理数定义的单个数学函数,因此适用于所有 int 实例和 fractions.Fraction,以及 floatdecimal.Decimal 的所有有限实例。本质上,该函数由固定质数 P 的按模 P 减少给出。 P 的值作为 sys.hash_infomodulus 属性提供给Python。

目前,主要使用的是具有32位C长度的机器上的 P = 2**31 - 1,以及具有64位C长度的机器上的 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.infsys.hash_info.nan 用作正无穷大,负无穷大或nans(分别)的哈希值。 (所有hashable都有相同的哈希值。)

  • 对于 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代码,等效于内置哈希,用于计算有理数的哈希值,floatcomplex:

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

4.5. 迭代器类型

Python支持对容器进行迭代的概念。这是使用两种不同的方法实现的;这些用于允许用户定义的类支持迭代。下面更详细地描述的序列总是支持迭代方法。

需要为容器对象定义一个方法以提供迭代支持:

container.__iter__()

返回一个迭代器对象。该对象需要支持下面描述的迭代器协议。如果容器支持不同类型的迭代,可以提供其他方法来专门请求这些迭代类型的迭代器。 (支持多种形式的迭代的对象的示例将是支持广度优先和深度优先遍历的树结构。)该方法对应于Python/C API中的Python对象的类型结构的 tp_iter 槽。

迭代器对象本身需要支持以下两种方法,它们一起形成 iterator protocol

iterator.__iter__()

返回迭代器对象本身。这是必需的,以允许容器和迭代器与 forin 语句一起使用。此方法对应于Python/C API中的Python对象的类型结构的 tp_iter 插槽。

iterator.__next__()

从容器中返回下一个项目。如果没有其他项目,请提出 StopIteration 异常。此方法对应于Python/C API中的Python对象的类型结构的 tp_iternext 插槽。

Python定义了几个迭代器对象以支持对一般和特定序列类型,字典和其他更专门的形式的迭代。除了它们的迭代器协议的实现之外,特定类型不重要。

一旦迭代器的 __next__() 方法提高 StopIteration,它必须在后续调用时继续这样做。不遵守此属性的实施将被视为已损坏。

4.5.1. 发电机类型

Python的 generator 提供了一种方便的方法来实现迭代器协议。如果容器对象的 __iter__() 方法被实现为一个生成器,它将自动返回一个提供 __iter__()__next__() 方法的迭代器对象(技术上,一个生成器对象)。有关发电机的更多信息,请参见 yield表达式的文档

4.6. 序列类型— listtuplerange

有三种基本的序列类型:列表,元组和范围对象。在专用章节中描述了为处理 二进制数据文本字符串 而定制的其它序列类型。

4.6.1. 公共序列操作

大多数序列类型支持下表中的操作,可变和不可变。提供 collections.abc.Sequence ABC以使其更容易在自定义序列类型上正确实现这些操作。

此表列出按升序排列的顺序操作。在表中,st 是相同类型的序列,nijk 是整数,x 是满足 s 施加的任何类型和值限制的任意对象。

innot in 操作具有与比较操作相同的优先级。 + (级联)和 * (重复)操作具有与相应数字运算相同的优先级。

操作

结果

笔记

x in s

True,如果 s 的项等于 x,否则为 False

(1)

x not in s

False,如果 s 的项等于 x,否则为 True

(1)

s + t

st 的连接

(6)(7)

s * nn * s

相当于将 s 添加到自身 n

(2)(7)

s[i]

i s 项,原点0

(3)

s[i:j]

切片的 sij

(3)(4)

s[i:j:k]

切片的 si 到具有步骤 kj

(3)(5)

len(s)

s 的长度

 

min(s)

s 的最小项目

 

max(s)

s 的最大项目

 

s.index(x[, i[, j]])

sx 的第一次出现的指数(在指数 i 之后或在指数 j 之前)

(8)

s.count(x)

s x 出现的总次数

 

相同类型的序列也支持比较。特别地,元组和列表通过比较相应元素来按字典顺序进行比较。这意味着为了比较等于,每个元素必须比较相等,并且两个序列必须是相同类型并且具有相同的长度。 (有关详细信息,请参阅语言参考中的 比较。)

笔记:

  1. 虽然 innot in 操作仅用于通常情况下的简单容纳测试,但是一些专用序列(例如 strbytesbytearray)也将它们用于子序列测试:

    >>> "gg" in "eggs"
    True
    
  2. n 小于 0 的值被视为 0 (其产生与 s 相同类型的空序列)。注意,序列 s 中的项目不被复制;它们被引用多次。这经常困扰着新的Python程序员;考虑:

    >>> lists = [[]] * 3
    >>> lists
    [[], [], []]
    >>> lists[0].append(3)
    >>> lists
    [[3], [3], [3]]
    

    发生的是 [[]] 是一个包含空列表的单元素列表,因此 [[]] * 3 的所有三个元素都是对此单个空列表的引用。修改 lists 的任何元素将修改此单个列表。您可以通过这种方式创建不同列表的列表:

    >>> lists = [[] for i in range(3)]
    >>> lists[0].append(3)
    >>> lists[1].append(5)
    >>> lists[2].append(7)
    >>> lists
    [[3], [5], [7]]
    

    有关详细说明,请参阅常见问题条目 如何创建多维列表?

  3. 如果 ij 为负,则索引相对于字符串的结尾:len(s) + ilen(s) + j 被替换。但请注意,-0 仍然是 0

  4. ijs 的切片被定义为具有索引 k 的项目序列,使得 i <= k < j。如果 ij 大于 len(s),请使用 len(s)。如果省略 iNone,请使用 0。如果省略 jNone,请使用 len(s)。如果 i 大于或等于 j,则切片为空。

  5. 具有步进 k 的从 ijs 的切片被定义为具有索引 x = i + n*k 的项目序列,使得 0 <= n < (j-i)/k。换句话说,索引是 ii+ki+2*ki+3*k 等,当达到 j 时停止(但不包括 j)。如果 ij 大于 len(s),则使用 len(s)。如果 ij 被省略或 None,它们变为“结束”值(结束取决于 k 的符号)。注意,k 不能为零。如果 kNone,它被视为 1

  6. 连接不可变序列总是导致一个新的对象。这意味着通过重复级联构建序列将在总序列长度中具有二次运行时成本。要获得线性运行时成本,必须切换到以下选项之一:

    • 如果连接 str 对象,可以构建一个列表,并在结尾使用 str.join(),否则写入 io.StringIO 实例,并在完成时检索其值

    • 如果连接 bytes 对象,您可以类似地使用 bytes.join()io.BytesIO,或者您可以与 bytearray 对象进行就地连接。 bytearray 对象是可变的并且具有有效的过分配机制

    • 如果连接 tuple 对象,请扩展 list

    • 对于其他类型,调查相关类文件

  7. 一些序列类型(例如 range)仅支持遵循特定模式的项序列,因此不支持序列连接或重复。

  8. 当在 s 中没有发现 x 时,index 产生 ValueError。当支持时,索引方法的附加参数允许有效搜索序列的子部分。传递额外的参数大致相当于使用 s[i:j].index(x),只是不复制任何数据,返回的索引相对于序列的开始,而不是切片的开始。

4.6.2. 不可变序列类型

不可变序列类型通常实现的唯一操作不是也由可变序列类型实现的是支持 hash() 内置。

此支持允许不可变序列(例如 tuple 实例)被用作 dict 密钥并存储在 setfrozenset 实例中。

尝试对包含不可缓冲值的不可变序列进行散列将导致 TypeError

4.6.3. 可变序列类型

下表中的操作是在可变序列类型上定义的。提供 collections.abc.MutableSequence ABC以使其更容易在自定义序列类型上正确实现这些操作。

在表中,s 是可变序列类型的实例,t 是任何可迭代对象,x 是满足 s 施加的任何类型和值限制的任意对象(例如,bytearray 仅接受满足值限制 0 <= x <= 255 的整数)。

操作

结果

笔记

s[i] = x

s 的项目 ix 替换

 

s[i:j] = t

ijs 的切片被可迭代 t 的内容替换

 

del s[i:j]

s[i:j] = [] 相同

 

s[i:j:k] = t

s[i:j:k] 的要素由 t 的要素替代

(1)

del s[i:j:k]

从列表中删除 s[i:j:k] 的元素

 

s.append(x)

x 附加到序列的末尾(与 s[len(s):len(s)] = [x] 相同)

 

s.clear()

删除 s 中的所有项目(与 del s[:] 相同)

(5)

s.copy()

创建 s 的浅拷贝(与 s[:] 相同)

(5)

s.extend(t)s += t

扩展 st 的内容(大部分与 s[len(s):len(s)] = t 相同)

 

s *= n

更新 s,其内容重复 n

(6)

s.insert(i, x)

x 以由 i 给出的索引(与 s[i:i] = [x] 相同)插入 s

 

s.pop([i])

i 检索项目,并从 s 中删除它

(2)

s.remove(x)

s 中删除第一个项目,其中 s[i] == x

(3)

s.reverse()

颠倒 s 的项目到位

(4)

笔记:

  1. t 必须具有与其替换的切片相同的长度。

  2. 可选参数 i 默认为 -1,因此默认情况下删除并返回最后一个项目。

  3. 当在 s 中没有发现 x 时,remove 产生 ValueError

  4. 当反转大序列时,reverse() 方法修改用于空间经济的序列。为了提醒用户它通过副作用操作,它不返回反向序列。

  5. 包括 clear()copy() 以与不支持切片操作的可变容器(例如 dictset)的接口一致,

    3.3 新版功能: clear()copy() 方法。

  6. n 是整数,或者是实现 __index__() 的对象。 n 的零值和负值清除序列。不复制序列中的项目;它们被引用多次,如在 公共序列操作 下针对 s * n 所解释的。

4.6.4. 列表

列表是可变序列,通常用于存储同类项目的集合(其中精确的相似程度将随应用程序而变化)。

class list([iterable])

列表可以以多种方式构建:

  • 使用一对方括号表示空列表:[]

  • 使用方括号,用逗号分隔项目:[a][a, b, c]

  • 使用列表解析:[x for x in iterable]

  • 使用类型构造函数:list()list(iterable)

构造函数构建一个列表,其项目与 iterable 的项目相同并且顺序相同。 iterable 可以是序列,支持迭代的容器或迭代器对象。如果 iterable 已经是一个列表,则会生成并返回一个副本,类似于 iterable[:]。例如,list('abc') 返回 ['a', 'b', 'c']list( (1, 2, 3) ) 返回 [1, 2, 3]。如果没有给出参数,构造函数将创建一个新的空列表 []

许多其他操作也生成列表,包括 sorted() 内置。

列表实现所有 共同可变 序列操作。列表还提供以下附加方法:

sort(*, key=None, reverse=None)

此方法对列表进行排序,只使用项目之间的 < 比较。异常不会被抑制 - 如果任何比较操作失败,整个排序操作将失败(并且列表可能会保留在部分修改状态)。

sort() 接受两个只能通过关键字(仅关键字参数)传递的参数:

key 指定用于从每个列表元素(例如,key=str.lower)提取比较键的一个参数的函数。对应于列表中的每个项目的键被计算一次,然后用于整个分类处理。 None 的默认值意味着列表项目被直接排序而不计算单独的键值。

functools.cmp_to_key() 实用程序可用于将2.x样式 cmp 函数转换为 key 函数。

reverse 是一个布尔值。如果设置为 True,那么列表元素将按照每个比较反转进行排序。

该方法在排序大序列时修改空间经济性的序列。要提醒用户它通过副作用操作,它不返回排序的序列(使用 sorted() 显式请求新的排序列表实例)。

sort() 方法保证稳定。如果保证不改变比较相等的元素的相对顺序,则排序是稳定的 - 这有助于在多个通过中排序(例如,按部门排序,然后按工资级排序)。

当列表被排序时,尝试改变,甚至检查列表的效果是未定义的。 Python的C实现使列表在持续时间内显示为空,并且如果它可以检测到列表在排序期间已变异,则提升 ValueError

4.6.5. 元组

元组是不可变序列,通常用于存储异构数据集合(例如由 enumerate() 内置产生的2元组)。元组还用于需要不变的同构数据序列(例如允许在 setdict 实例中存储)的情况。

class tuple([iterable])

元组可以以多种方式构建:

  • 使用一对括号来表示空元组:()

  • 对单个元组使用尾随逗号:a,(a,)

  • 用逗号分隔项目:a, b, c(a, b, c)

  • 使用 tuple() 内置:tuple()tuple(iterable)

构造函数构建一个元组,其项目与 iterable 的项目相同并且顺序相同。 iterable 可以是序列,支持迭代的容器或迭代器对象。如果 iterable 已经是一个元组,则不会改变地返回。例如,tuple('abc') 返回 ('a', 'b', 'c')tuple( [1, 2, 3] ) 返回 (1, 2, 3)。如果没有给出参数,那么构造函数创建一个新的空元组 ()

注意,它实际上是一个逗号,它使一个元组,而不是括号。括号是可选的,除非在空元组的情况下,或者当需要它们以避免语法模糊时。例如,f(a, b, c) 是具有三个参数的函数调用,而 f((a, b, c)) 是具有3元组作为唯一参数的函数调用。

元组实现所有 共同 序列操作。

对于异名数据集合,其中按名称访问比通过索引访问更清楚,collections.namedtuple() 可能是比简单元组对象更合适的选择。

4.6.6. 范围

range 类型表示不可变的数字序列,并且通常用于在 for 循环中循环特定次数。

class range(stop)
class range(start, stop[, step])

范围构造函数的参数必须是整数(内置 int 或实现 __index__ 特殊方法的任何对象)。如果省略 step 参数,它将默认为 1。如果省略 start 参数,它将默认为 0。如果 step 为零,则提高 ValueError

对于阳性 step,范围 r 的含量由公式 r[i] = start + step*i 确定,其中 i >= 0r[i] < stop

对于负 step,范围的内容仍然由公式 r[i] = start + step*i 确定,但是约束是 i >= 0r[i] > stop

如果 r[0] 不满足值约束,范围对象将为空。范围确实支持负指数,但是这些被解释为从由正指数确定的序列的结尾处的索引。

允许包含大于 sys.maxsize 的绝对值的范围,但是一些特征(例如 len())可以产生 OverflowError

范围示例:

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))
[]
>>> list(range(1, 0))
[]

范围实现除了连接和重复之外的所有 共同 序列操作(由于范围对象只能表示遵循严格模式的序列并且重复和连接通常违反该模式)。

start

start 参数的值(如果未提供参数,则为 0

stop

stop 参数的值

step

step 参数的值(如果未提供参数,则为 1

range 类型相对于常规 listtuple 的优点是 range 对象将总是占用相同(小)量的存储器,而不管它表示的范围的大小(因为它仅存储 startstopstep 值,根据需要计算各个项目和子范围)。

范围对象实现 collections.abc.Sequence ABC,并提供诸如遏制测试,元素索引查找,切片和支持负指数(见 序列类型— list,tuple,range)等功能:

>>> r = range(0, 20, 2)
>>> r
range(0, 20, 2)
>>> 11 in r
False
>>> 10 in r
True
>>> r.index(10)
5
>>> r[5]
10
>>> r[:5]
range(0, 10, 2)
>>> r[-1]
18

测试与 ==!= 相等的范围对象将它们作为序列进行比较。也就是说,如果两个范围对象表示相同的值序列,则它们被认为是相等的。 (注意,比较相等的两个范围对象可能具有不同的 startstopstep 属性,例如 range(0) == range(2, 1, 3)range(0, 3, 2) == range(0, 4, 2)。)

在 3.2 版更改: 实现序列ABC。支持切片和负指数。测试 int 对象在常量时间的成员资格,而不是遍历所有项目。

在 3.3 版更改: 定义“==”和“!=”以根据它们定义的值的顺序来比较范围对象(而不是基于对象标识进行比较)。

3.3 新版功能: startstopstep 属性。

参见

  • linspace食谱 展示了如何实现适合于浮点应用程序的惰性版本的范围。

4.7. 文本序列类型— str

Python中的文本数据由 str 对象或 strings 处理。字符串是Unicode代码点的不可变 序列。字符串文字以多种方式编写:

  • 单引号:'allows embedded "double" quotes'

  • 双引号:"allows embedded 'single' quotes"

  • 三重引用:'''Three single quotes'''"""Three double quotes"""

三次引用的字符串可以跨越多行 - 所有关联的空格将包含在字符串文字中。

作为单个表达式的一部分且在它们之间只有空格的字符串文字将被隐式转换为单个字符串文字。也就是说,("spam " "eggs") == "spam eggs"

有关字符串文字的各种形式的更多信息,包括支持的转义序列和禁止大多数转义序列处理的 r (“原始”)前缀,请参阅 字符串和字节字面值

字符串也可以使用 str 构造函数从其他对象创建。

由于没有单独的“字符”类型,索引字符串产生长度为1的字符串。也就是说,对于非空字符串 ss[0] == s[0:1]

也没有可变字符串类型,但是 str.join()io.StringIO 可以用于从多个片段有效地构造字符串。

在 3.3 版更改: 为了向后兼容Python 2系列,在字符串字面上再次允许 u 前缀。它对字符串文字的含义没有影响,不能与 r 前缀组合。

class str(object='')
class str(object=b'', encoding='utf-8', errors='strict')

返回 版本的 object。如果未提供 object,则返回空字符串。否则,str() 的行为取决于是否给出 encodingerrors,如下。

如果既没有给出 encoding 也没有给出 errors,则 str(object) 返回 object.__str__(),它是 object 的“非正式”或可打印的字符串表示。对于字符串对象,这是字符串本身。如果 object 不具有 __str__() 方法,则 str() 回退到返回 repr(object)

如果给出 encodingerrors 中的至少一个,则 object 应当是 bytes-like object (例如 bytesbytearray)。在这种情况下,如果 objectbytes (或 bytearray)对象,则 str(bytes, encoding, errors) 等价于 bytes.decode(encoding, errors)。否则,在调用 bytes.decode() 之前获取缓冲对象下面的字节对象。有关缓冲区对象的信息,请参阅 二进制序列类型— bytes,bytearray,memoryview缓冲区协议

在没有 encodingerrors 参数的情况下将 bytes 对象传递到 str() 属于返回非正式字符串表示形式的第一种情况(另请参阅 -b 命令行选项到Python)。例如:

>>> str(b'Zoot!')
"b'Zoot!'"

有关 str 类及其方法的更多信息,请参阅下面的 文本序列类型— str字符串方法 部分。要输出格式化的字符串,请参见 格式化字符串文字格式字符串语法 部分。此外,请参阅 文本处理服务 部分。

4.7.1. 字符串方法

字符串实现所有 共同 序列操作,以及下面描述的附加方法。

字符串还支持两种样式的字符串格式化,一种提供大量的灵活性和定制(参见 str.format()格式字符串语法自定义字符串格式),另一种基于C printf 格式化,处理较窄范围的类型,并且稍微难以正确使用,但对于它可以处理的情况(printf 样式字符串格式)通常更快。

标准库的 文本处理服务 部分涵盖了许多提供各种文本相关实用程序(包括 re 模块中的正则表达式支持)的其他模块。

str.capitalize()

返回字符串的副本,其中第一个字符大写,其余的小写。

str.casefold()

返回字符串的casefolded副本。表壳式字符串可用于无盒匹配。

casefolding类似于小写,但更积极,因为它旨在删除字符串中的所有case区分。例如,德国小写字母 'ß' 等同于 "ss"。由于它已经是小写的,lower()'ß' 什么都不做; casefold() 将其转换为 "ss"

表单加载算法在Unicode标准的3.13节中描述。

3.3 新版功能.

str.center(width[, fillchar])

返回以长度为 width 的字符串为中心。填充使用指定的 fillchar (默认为ASCII空格)完成。如果 width 小于或等于 len(s),则返回原始字符串。

str.count(sub[, start[, end]])

返回在[startend]范围内的子字符串 sub 的不重叠出现次数。可选参数 startend 被解释为切片符号。

str.encode(encoding="utf-8", errors="strict")

将字符串的编码版本作为字节对象返回。默认编码是 'utf-8'。可以给予 errors 以设置不同的错误处理方案。 errors 的默认值为 'strict',这意味着编码错误会引发 UnicodeError。其他可能的值为 'ignore''replace''xmlcharrefreplace''backslashreplace' 和通过 codecs.register_error() 注册的任何其他名称,请参见 错误处理程序。有关可能的编码列表,请参见第 标准编码 节。

在 3.1 版更改: 支持添加关键字参数。

str.endswith(suffix[, start[, end]])

如果字符串以指定的 suffix 结束,则返回 True,否则返回 Falsesuffix 也可以是一个元组的后缀寻找。使用可选的 start,测试从该位置开始。使用可选的 end,停止在该位置的比较。

str.expandtabs(tabsize=8)

返回一个字符串的副本,其中所有制表符由一个或多个空格替换,具体取决于当前列和给定的制表符大小。标签位置每个 tabsize 字符出现(默认值为8,在第0,8,16列等位置提供标签位置)。要扩展字符串,当前列设置为零,字符串逐个字符检查。如果字符是制表符(\t),则在结果中插入一个或多个空格字符,直到当前列等于下一个制表符位置。 (不复制制表符字符本身。)如果字符是换行符(\n)或返回(\r),则复制该字符,并将当前列重置为零。任何其他字符不变地复制,并且当前列增加1,而不管在打印时如何表示字符。

>>> '01\t012\t0123\t01234'.expandtabs()
'01      012     0123    01234'
>>> '01\t012\t0123\t01234'.expandtabs(4)
'01  012 0123    01234'
str.find(sub[, start[, end]])

返回在片段 s[start:end] 中找到子串 sub 的字符串中的最低索引。可选参数 startend 解释为切片符号。如果未找到 sub,则返回 -1

注解

只有在您需要知道 sub 的位置时,才应使用 find() 方法。要检查 sub 是否是子字符串,请使用 in 运算符:

>>> 'Py' in 'Python'
True
str.format(*args, **kwargs)

执行字符串格式化操作。调用此方法的字符串可以包含由大括号 {} 分隔的文本文本或替换字段。每个替换字段包含位置参数的数字索引或关键字参数的名称。返回字符串的副本,其中每个替换字段都替换为相应参数的字符串值。

>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'

有关可以在格式字符串中指定的各种格式选项的说明,请参阅 格式字符串语法

str.format_map(mapping)

str.format(**mapping) 类似,除了 mapping 直接使用并且不复制到 dict。这是有用的,如果例如 mapping 是一个dict子类:

>>> class Default(dict):
...     def __missing__(self, key):
...         return key
...
>>> '{name} was born in {country}'.format_map(Default(name='Guido'))
'Guido was born in country'

3.2 新版功能.

str.index(sub[, start[, end]])

find(),但是当未找到子字符串时提高 ValueError

str.isalnum()

如果字符串中的所有字符都是字母数字且至少有一个字符,则返回true,否则返回false。字符 c 是字母数字的,如果以下之一返回 Truec.isalpha()c.isdecimal()c.isdigit()c.isnumeric()

str.isalpha()

如果字符串中的所有字符都是字母并且至少有一个字符,则返回true,否则返回false。字母字符是在Unicode字符数据库中被定义为“Letter”的那些字符,即,具有一般类别属性是“Lm”,“Lt”,“Lu”,“Ll”或“Lo”之一的字符。请注意,这不同于Unicode标准中定义的“字母”属性。

str.isdecimal()

如果字符串中的所有字符都是十进制字符,并且至少有一个字符,则返回true,否则返回false。十进制字符是来自通用类别“Nd”的字符。这个类别包括数字字符,以及可用于形成十进制数字的所有字符。 U + 0660,ARABIC-INDIC DIGIT ZERO。

str.isdigit()

如果字符串中的所有字符都是数字并且至少有一个字符,则返回true,否则返回false。数字包括十进制字符和需要特殊处理的数字,例如兼容性上标数字。形式上,数字是具有属性值Numeric_Type = Digit或Numeric_Type = Decimal的字符。

str.isidentifier()

如果字符串是根据语言定义(标识符和关键字 部分)的有效标识符,则返回true。

使用 keyword.iskeyword() 测试保留的标识符,例如 defclass

str.islower()

如果字符串中所有包含字符的 [4] 都为小写,并且至少有一个套接字符,则返回true,否则返回false。

str.isnumeric()

如果字符串中的所有字符都是数字字符,并且至少有一个字符,则返回true,否则返回false。数字字符包括数字字符,以及具有Unicode数字值属性的所有字符。 U + 2155,VULGAR FRACTION ONE FIFTH。正式地,数字字符是具有属性值Numeric_Type = Digit,Numeric_Type = Decimal或Numeric_Type = Numeric的那些。

str.isprintable()

如果字符串中的所有字符都可打印或字符串为空,则返回true,否则返回false。不可打印字符是在Unicode字符数据库中定义为“其他”或“分隔符”的字符,但被认为是可打印的ASCII空间(0x20)除外。 (请注意,在此上下文中的可打印字符是在字符串上调用 repr() 时不应转义的字符,它与处理写入 sys.stdoutsys.stderr 的字符串无关。)

str.isspace()

如果字符串中只有空格字符,并且至少有一个字符,则返回true,否则返回false。空格字符是在Unicode字符数据库中定义为“其他”或“分隔符”并且具有双向属性是“WS”,“B”或“S”之一的那些字符。

str.istitle()

如果字符串是一个标题字符串并且至少有一个字符,则返回true,例如,大写字符只能跟随未编写的字符,小写字符只能使用加壳的字符。否则返回false。

str.isupper()

如果字符串中的所有套管字符 [4] 都是大写,并且至少有一个套接字符,则返回true,否则返回false。

str.join(iterable)

返回一个字符串,它是 iterable iterable 中字符串的并置。如果 iterable 中有任何非字符串值,包括 bytes 对象,则会引发 TypeError。元素之间的分隔符是提供此方法的字符串。

str.ljust(width[, fillchar])

返回长度为 width 的字符串中左对齐的字符串。填充使用指定的 fillchar (默认为ASCII空格)完成。如果 width 小于或等于 len(s),则返回原始字符串。

str.lower()

返回一个字符串的副本,所有包含字符的 [4] 转换为小写。

使用的小写算法在Unicode标准的3.13节中描述。

str.lstrip([chars])

返回带有前导字符的字符串的副本。 chars 参数是一个字符串,指定要删除的字符集。如果省略或 Nonechars 参数默认为删除空格。 chars 参数不是前缀;相反,其值的所有组合都被去除:

>>> '   spacious   '.lstrip()
'spacious   '
>>> 'www.example.com'.lstrip('cmowz.')
'example.com'
static str.maketrans(x[, y[, z]])

此静态方法返回可用于 str.translate() 的转换表。

如果只有一个参数,它必须是将Unicode ordinals(整数)或字符(长度为1的字符串)映射到Unicode ordinal,字符串(任意长度)或 None 的字典。字符键将被转换为序数。

如果有两个参数,它们必须是相等长度的字符串,并且在结果字典中,x中的每个字符都将映射到y中相同位置的字符。如果有第三个参数,它必须是一个字符串,其字符将被映射到结果中的 None

str.partition(sep)

在第一次出现 sep 时分割字符串,并返回包含分隔符之前的部分,分隔符本身和分隔符后面的部分的3元组。如果找不到分隔符,则返回包含字符串本身的3元组,后跟两个空字符串。

str.replace(old, new[, count])

返回包含所有出现的子字符串 old 的字符串的副本,替换为 new。如果给出了可选参数 count,则只替换第一个 count 出现。

str.rfind(sub[, start[, end]])

返回字符串中找到子串 sub 的最高索引,以便 sub 包含在 s[start:end] 中。可选参数 startend 被解释为切片符号。失败时返回 -1

str.rindex(sub[, start[, end]])

rfind(),但当没有找到子字符串 sub 时提高 ValueError

str.rjust(width[, fillchar])

返回长度为 width 的字符串右对齐的字符串。填充使用指定的 fillchar (默认为ASCII空格)完成。如果 width 小于或等于 len(s),则返回原始字符串。

str.rpartition(sep)

拆分 sep 最后一次出现时的字符串,并返回包含分隔符之前的部分,分隔符本身和分隔符后面的部分的3元组。如果找不到分隔符,则返回包含两个空字符串的3元组,后跟字符串本身。

str.rsplit(sep=None, maxsplit=-1)

返回字符串中的单词的列表,使用 sep 作为分隔符字符串。如果给出 maxsplit,则最多进行 maxsplit 分裂,rightmost 分裂。如果未指定 sepNone,则任何空格字符串都是分隔符。除了从右边分开,rsplit() 表现得像 split(),这将在下面详细描述。

str.rstrip([chars])

返回删除了尾随字符的字符串的副本。 chars 参数是一个字符串,指定要删除的字符集。如果省略或 Nonechars 参数默认为删除空格。 chars 参数不是后缀;相反,其值的所有组合都被去除:

>>> '   spacious   '.rstrip()
'   spacious'
>>> 'mississippi'.rstrip('ipz')
'mississ'
str.split(sep=None, maxsplit=-1)

返回字符串中的单词的列表,使用 sep 作为分隔符字符串。如果给出 maxsplit,则最多进行 maxsplit 分割(因此,列表将具有至多 maxsplit+1 个元素)。如果未指定 maxsplit-1,则对分割数量没有限制(进行所有可能的分割)。

如果给出了 sep,则连续的分隔符不会分组在一起,并被视为定界空字符串(例如,'1,,2'.split(',') 返回 ['1', '', '2'])。 sep 参数可以由多个字符组成(例如,'1<>2<>3'.split('<>') 返回 ['1', '2', '3'])。使用指定的分隔符拆分空字符串将返回 ['']

例如:

>>> '1,2,3'.split(',')
['1', '2', '3']
>>> '1,2,3'.split(',', maxsplit=1)
['1', '2,3']
>>> '1,2,,3,'.split(',')
['1', '2', '', '3', '']

如果未指定 sep 或为 None,则应用不同的分割算法:连续空格的运行被视为单个分隔符,如果字符串具有前导或尾随空格,则结果将在开始或结束处不包含空字符串。因此,使用 None 分隔符分隔空字符串或仅包含空格的字符串将返回 []

例如:

>>> '1 2 3'.split()
['1', '2', '3']
>>> '1 2 3'.split(maxsplit=1)
['1', '2 3']
>>> '   1   2   3   '.split()
['1', '2', '3']
str.splitlines([keepends])

返回字符串中的行的列表,在行边界处断开。换行符不包括在结果列表中,除非给出了 keepends 和true。

此方法在以下行边界上分割。特别地,边界是 universal newlines 的超集。

表示

描述

\n

换行

\r

回车

\r\n

回车+换行

\v\x0b

线制表

\f\x0c

表单Feed

\x1c

文件分隔符

\x1d

组分隔符

\x1e

记录分隔符

\x85

下一行(C1控制代码)

\u2028

行分隔符

\u2029

段落分隔符

在 3.2 版更改: \v\f 添加到行边界列表。

例如:

>>> 'ab c\n\nde fg\rkl\r\n'.splitlines()
['ab c', '', 'de fg', 'kl']
>>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
['ab c\n', '\n', 'de fg\r', 'kl\r\n']

与给定分隔符字符串 sep 时的 split() 不同,此方法为空字符串返回空列表,并且终端行断开不会产生额外行:

>>> "".splitlines()
[]
>>> "One line\n".splitlines()
['One line']

为了比较,split('\n') 给出:

>>> ''.split('\n')
['']
>>> 'Two lines\n'.split('\n')
['Two lines', '']
str.startswith(prefix[, start[, end]])

如果字符串以 prefix 开头,则返回 True,否则返回 Falseprefix 也可以是一个元组的前缀寻找。使用可选的 start,测试字符串从该位置开始。使用可选的 end,停止比较该位置的字符串。

str.strip([chars])

返回字符串的前导和尾随字符删除的副本。 chars 参数是一个字符串,指定要删除的字符集。如果省略或 Nonechars 参数默认为删除空格。 chars 参数不是前缀或后缀;相反,其值的所有组合都被去除:

>>> '   spacious   '.strip()
'spacious'
>>> 'www.example.com'.strip('cmowz.')
'example'

从字符串中剥离最外面的前导和尾部 chars 参数值。字符从前端移除,直到到达不包含在 chars 中的字符集合中的字符串字符。类似的动作发生在尾端。例如:

>>> comment_string = '#....... Section 3.2.1 Issue #32 .......'
>>> comment_string.strip('.#! ')
'Section 3.2.1 Issue #32'
str.swapcase()

返回大写字符的字符串的副本转换为小写,反之亦然。注意,s.swapcase().swapcase() == s 不一定是真的。

str.title()

返回字符串的拼写版本,其中单词以大写字符开头,其余字符为小写。

例如:

>>> 'Hello world'.title()
'Hello World'

该算法使用单词的简单的语言无关定义作为连续字母的组。该定义在许多上下文中工作,但它意味着收缩和占有的撇号形成词边界,这可能不是期望的结果:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

可以使用正则表达式构造撇号的解决方法:

>>> import re
>>> def titlecase(s):
...     return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
...                   lambda mo: mo.group(0)[0].upper() +
...                              mo.group(0)[1:].lower(),
...                   s)
...
>>> titlecase("they're bill's friends.")
"They're Bill's Friends."
str.translate(table)

返回通过给定的翻译表映射每个字符的字符串的副本。该表必须是通过 __getitem__() 实现索引的对象,通常是 mappingsequence。当以Unicode序号(整数)索引时,表对象可以执行以下任何操作:返回Unicode序号或字符串,将字符映射到一个或多个其他字符;返回 None,从返回字符串中删除字符;或引发 LookupError 异常,将字符映射到自身。

您可以使用 str.maketrans() 从不同格式的字符到字符映射创建转换映射。

另见 codecs 模块,用于更灵活的自定义字符映射方法。

str.upper()

返回一个字符串的副本,所有包含字符的 [4] 转换为大写。注意,如果 s 包含未编码的字符,或者如果结果字符的Unicode类别不是“Lu”(Letter,大写),则 str.upper().isupper() 可能是 False, “Lt”(Letter,titlecase)。

使用的大写算法在Unicode标准的3.13节中描述。

str.zfill(width)

返回剩余的ASCII字符 '0' 数字的字符串的副本,以使长度为 width 的字符串。前导符前缀('+'/'-')通过插入填充符 after 而不是之前的符号字符来处理。如果 width 小于或等于 len(s),则返回原始字符串。

例如:

>>> "42".zfill(5)
'00042'
>>> "-42".zfill(5)
'-0042'

4.7.2. printf 样式字符串格式

注解

这里描述的格式化操作展示了导致多个常见错误(例如未能正确地显示元组和字典)的各种怪癖。使用较新的 格式化的字符串文字str.format() 接口有助于避免这些错误。这些替代方案还提供了更强大,灵活和可扩展的方法来格式化文本。

字符串对象有一个独特的内置操作:% 运算符(模)。这也称为字符串 formattinginterpolation 运算符。给定 format % values (其中 format 是字符串),format 中的 % 转换规范被 values 的零个或多个元素替换。效果类似于在C语言中使用 sprintf()

如果 format 需要单个参数,则 values 可以是单个非元组对象。 [5] 否则,values 必须是由格式字符串或单个映射对象(例如,字典)指定的项目数量的元组。

转换说明符包含两个或多个字符,并具有以下组件,它们必须按此顺序发生:

  1. '%' 字符,它标记了说明符的开始。

  2. 映射键(可选),由括号中的字符序列(例如,(somename))组成。

  3. 转换标志(可选),会影响某些转换类型的结果。

  4. 最小字段宽度(可选)。如果指定为 '*' (星号),则从 values 中元组的下一个元素读取实际宽度,要转换的对象在最小字段宽度和可选精度之后。

  5. 精度(可选),以 '.' (点)形式给出,后跟精度。如果指定为 '*' (星号),则从 values 中的元组的下一个元素读取实际精度,并且要转换的值在精度之后。

  6. 长度修饰符(可选)。

  7. 转换类型。

当右参数是字典(或其他映射类型)时,字符串 must 中的格式包括在紧接在 '%' 字符之后插入的字典中的括号映射键。映射键从映射中选择要格式化的值。例如:

>>> print('%(language)s has %(number)03d quote types.' %
...       {'language': "Python", "number": 2})
Python has 002 quote types.

在这种情况下,在格式中不会出现 * 说明符(因为它们需要顺序参数列表)。

转换标志字符有:

含义

'#'

值转换将使用“备用形式”(以下定义)。

'0'

转换将被零填充为数值。

'-'

转换后的值将被调整(如果同时给出 '0' 转换,则覆盖 '0' 转换)。

' '

(空格)空格应留在由带符号的转换产生的正数(或空字符串)之前。

'+'

符号字符('+''-')将在转换之前(覆盖“空格”标志)。

长度修饰符(hlL)可以存在,但是被忽略,因为对于Python不是必需的。 %ld%d 相同。

转换类型有:

转换

含义

笔记

'd'

有符号整数十进制。

 

'i'

有符号整数十进制。

 

'o'

带符号的八进制值。

(1)

'u'

过时类型 - 它与 'd' 相同。

(7)

'x'

带符号的十六进制(小写)。

(2)

'X'

带符号的十六进制(大写)。

(2)

'e'

浮点指数格式(小写)。

(3)

'E'

浮点指数格式(大写)。

(3)

'f'

浮点十进制格式。

(3)

'F'

浮点十进制格式。

(3)

'g'

浮点格式。如果指数小于-4或不小于精度,则使用小写指数格式,否则使用十进制格式。

(4)

'G'

浮点格式。如果指数小于-4或不小于精度,则使用大写指数格式,否则使用十进制格式。

(4)

'c'

单字符(接受整数或单字符字符串)。

 

'r'

String(使用 repr() 转换任何Python对象)。

(5)

's'

String(使用 str() 转换任何Python对象)。

(5)

'a'

String(使用 ascii() 转换任何Python对象)。

(5)

'%'

不转换参数,在结果中产生 '%' 字符。

 

笔记:

  1. 如果结果的前导字符不是零,则替换形式使得前导零('0')插入在左侧填充和数字的格式化之间。

  2. 如果结果的前导字符不是零,则替代形式导致前导 '0x''0X' (取决于是否使用 'x''X' 格式)插入左侧填充和数字的格式化之间。

  3. 备用形式使结果始终包含小数点,即使后面没有数字。

    精度确定小数点后的位数,默认为6。

  4. 替代形式导致结果始终包含小数点,并且后续零不会被删除,因为它们将是。

    精度确定小数点前后的有效数字的数量,默认为6。

  5. 如果precision是 N,则输出将被截断为 N 个字符。

  1. PEP 237

由于Python字符串具有显式长度,因此 %s 转换不假定 '\0' 是字符串的结尾。

在 3.1 版更改: 绝对值超过1e50的数字的 %f 转换不再被 %g 转换取代。

4.8. 二进制序列类型— bytesbytearraymemoryview

用于操作二进制数据的核心内置类型是 bytesbytearray。它们由 memoryview 支持,它使用 缓冲协议 访问其他二进制对象的内存,而不需要复制。

array 模块支持高效存储基本数据类型,如32位整数和IEEE754双精度浮点值。

4.8.1. 字节

字节对象是单字节的不可变序列。由于许多主要的二进制协议基于ASCII文本编码,因此字节对象提供了几种方法,这些方法仅在使用ASCII兼容数据时有效,并且以各种其他方式与字符串对象密切相关。

首先,字节字面量的语法与字符串字面量的语法大致相同,除了添加了 b 前缀:

  • 单引号:b'still allows embedded "double" quotes'

  • 双引号:b"still allows embedded 'single' quotes"

  • 三重引用:b'''3 single quotes'''b"""3 double quotes"""

字节字面值只允许ASCII字符(不考虑声明的源代码编码)。任何超过127的二进制值必须使用适当的转义序列输入字节字面值。

与字符串文字一样,字节字面量也可以使用 r 前缀来禁止转义序列的处理。有关字节字面量的各种形式的更多信息,包括支持的转义序列,请参阅 字符串和字节字面值

虽然字节字面值和表示是基于ASCII文本,但是字节对象实际上表现为不变的整数序列,序列中的每个值都受到限制,使得 0 <= x < 256 (尝试违反此限制将触发 ValueError)。这是有意地强调,二进制格式包括基于ASCII的元素,并且可以用一些面向文本的算法有效地操作,对于任意二进制数据通常不是这种情况(盲文地将文本处理算法应用于不是ASCII兼容的二进制数据格式通常会导致数据损坏) 。

除了字面形式,字节对象可以用许多其他方式创建:

  • 指定长度的零填充字节对象:bytes(10)

  • 从整数的可迭代:bytes(range(20))

  • 通过缓冲协议复制现有的二进制数据:bytes(obj)

另请参阅 字节 内置。

由于2个十六进制数字精确地对应于单个字节,所以十六进制数字是用于描述二进制数据的通常使用的格式。因此,字节类型具有以该格式读取数据的附加类方法:

classmethod bytes.fromhex(string)

这个 bytes 类方法返回一个字节对象,解码给定的字符串对象。该字符串必须包含每个字节两个十六进制数字,忽略ASCII空格。

>>> bytes.fromhex('2Ef0 F1f2  ')
b'.\xf0\xf1\xf2'

存在一个反向转换函数将一个字节对象转换为十六进制表示。

bytes.hex()

返回一个字符串对象,其中包含实例中每个字节的两个十六进制数字。

>>> b'\xf0\xf1\xf2'.hex()
'f0f1f2'

3.5 新版功能.

由于字节对象是整数序列(类似于元组),对于字节对象 bb[0] 将是整数,而 b[0:1] 将是长度为1的字节对象。(这与文本字符串形成对比,其中索引和切片都将产生长度为1的字符串)

字节对象的表示使用文字格式(b'...'),因为它通常比例如。 bytes([46, 46, 46])。您总是可以使用 list(b) 将字节对象转换为整数列表。

注解

对于Python 2.x用户:在Python 2.x系列中,允许在8位字符串(最接近2.x提供给内置二进制数据类型)和Unicode字符串之间进行各种隐式转换。这是一个向后兼容性的解决方法,因为Python最初只支持8位文本,而Unicode文本是后来添加的事实。在Python 3.x中,这些隐式转换消失了 - 8位二进制数据和Unicode文本之间的转换必须是显式的,字节和字符串对象总是比较不等。

4.8.2. Bytearray对象

bytearray 对象是 bytes 对象的可变对象。字节数组对象没有专用的文字语法,而是通过调用构造函数来创建它们:

  • 创建空实例:bytearray()

  • 创建一个给定长度的零填充实例:bytearray(10)

  • 从整数的可迭代:bytearray(range(20))

  • 通过缓冲协议复制现有的二进制数据:bytearray(b'Hi!')

由于bytearray对象是可变的,它们支持除了 字节和Bytearray操作 中描述的公共字节和bytearray操作之外的 可变 序列操作。

另请参阅 bytearray 内置。

由于2个十六进制数字精确地对应于单个字节,所以十六进制数字是用于描述二进制数据的通常使用的格式。因此,bytearray类型具有一个附加类方法来读取该格式的数据:

classmethod bytearray.fromhex(string)

这个 bytearray 类方法返回bytearray对象,解码给定的字符串对象。该字符串必须包含每个字节两个十六进制数字,忽略ASCII空格。

>>> bytearray.fromhex('2Ef0 F1f2  ')
bytearray(b'.\xf0\xf1\xf2')

存在一个逆转换函数将一个bytearray对象转换为十六进制表示。

bytearray.hex()

返回一个字符串对象,其中包含实例中每个字节的两个十六进制数字。

>>> bytearray(b'\xf0\xf1\xf2').hex()
'f0f1f2'

3.5 新版功能.

由于bytearray对象是整数序列(类似于列表),对于一个bytearray对象 bb[0] 将是一个整数,而 b[0:1] 将是一个长度为1的bytearray对象。(这与文本字符串形成对比,其中索引和切片都将产生长度为1的字符串)

bytearray对象的表示使用字节字面格式(bytearray(b'...')),因为它通常比例如。 bytearray([46, 46, 46])。您总是可以使用 list(b) 将一个bytearray对象转换为一个整数列表。

4.8.3. 字节和Bytearray操作

字节和bytearray对象都支持 共同 序列操作。它们不仅与相同类型的操作数互操作,而且与任何 bytes-like object 互操作。由于这种灵活性,它们可以在操作中自由混合而不引起错误。但是,结果的返回类型可能取决于操作数的顺序。

注解

字节和bytearray对象的方法不接受字符串作为它们的参数,就像字符串上的方法不接受字节作为它们的参数一样。例如,你必须写:

a = "abc"
b = a.replace("a", "f")

和:

a = b"abc"
b = a.replace(b"a", b"f")

一些字节和bytearray操作假定使用ASCII兼容的二进制格式,因此在使用任意二进制数据时应避免使用。这些限制如下。

注解

使用这些基于ASCII的操作来处理未以ASCII格式存储的二进制数据可能导致数据损坏。

字节和bytearray对象的以下方法可以与任意二进制数据一起使用。

bytes.count(sub[, start[, end]])
bytearray.count(sub[, start[, end]])

返回范围[startend]中的子序列 sub 的非重叠出现次数。可选参数 startend 被解释为切片符号。

要搜索的子序列可以是任何 bytes-like object 或范围为0到255的整数。

在 3.3 版更改: 也接受范围为0到255的整数作为子序列。

bytes.decode(encoding="utf-8", errors="strict")
bytearray.decode(encoding="utf-8", errors="strict")

返回从给定字节解码的字符串。默认编码是 'utf-8'。可以给予 errors 以设置不同的错误处理方案。 errors 的默认值为 'strict',这意味着编码错误会引发 UnicodeError。其他可能的值是 'ignore''replace' 和通过 codecs.register_error() 注册的任何其他名称,请参见 错误处理程序。有关可能编码的列表,请参见 标准编码 部分。

注解

encoding 参数传递给 str 允许直接解码任何 bytes-like object,而不需要创建临时字节或bytearray对象。

在 3.1 版更改: 添加对关键字参数的支持。

bytes.endswith(suffix[, start[, end]])
bytearray.endswith(suffix[, start[, end]])

如果二进制数据以指定的 suffix 结束,则返回 True,否则返回 Falsesuffix 也可以是一个元组的后缀寻找。使用可选的 start,测试从该位置开始。使用可选的 end,停止在该位置的比较。

要搜索的后缀可以是任何 bytes-like object

bytes.find(sub[, start[, end]])
bytearray.find(sub[, start[, end]])

返回找到子序列 sub 的数据中的最低索引,使得 sub 包含在切片 s[start:end] 中。可选参数 startend 被解释为切片符号。如果未找到 sub,则返回 -1

要搜索的子序列可以是任何 bytes-like object 或范围为0到255的整数。

注解

只有在您需要知道 sub 的位置时,才应使用 find() 方法。要检查 sub 是否是子字符串,请使用 in 运算符:

>>> b'Py' in b'Python'
True

在 3.3 版更改: 也接受范围为0到255的整数作为子序列。

bytes.index(sub[, start[, end]])
bytearray.index(sub[, start[, end]])

find(),但是当未找到子序列时提高 ValueError

要搜索的子序列可以是任何 bytes-like object 或范围为0到255的整数。

在 3.3 版更改: 也接受范围为0到255的整数作为子序列。

bytes.join(iterable)
bytearray.join(iterable)

返回一个字节或bytearray对象,它是 iterable iterable 中二进制数据序列的串联。如果 iterable 中有任何不是 字节状对象 的值,包括 str 对象,则会引发 TypeError。元素之间的分隔符是提供此方法的字节或bytearray对象的内容。

static bytes.maketrans(from, to)
static bytearray.maketrans(from, to)

这个静态方法返回一个可用于 bytes.translate() 的转换表,它将 from 中的每个字符映射到 to 中相同位置的字符; fromto 必须都是 字节状对象 并且具有相同的长度。

3.1 新版功能.

bytes.partition(sep)
bytearray.partition(sep)

在第一次出现 sep 时分割序列,并返回包含分隔符之前的部分,分隔符和分隔符后面的部分的3元组。如果找不到分隔符,则返回包含原始序列副本的3元组,后跟两个空字节或bytearray对象。

要搜索的分隔符可以是任何 bytes-like object

bytes.replace(old, new[, count])
bytearray.replace(old, new[, count])

返回序列的副本,所有出现的子序列 oldnew 替换。如果给出了可选参数 count,则只替换第一个 count 出现。

搜索的子序列及其替换可以是任何 bytes-like object

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.rfind(sub[, start[, end]])
bytearray.rfind(sub[, start[, end]])

返回其中找到子序列 sub 的序列中的最高索引,使得 sub 包含在 s[start:end] 内。可选参数 startend 被解释为切片符号。失败时返回 -1

要搜索的子序列可以是任何 bytes-like object 或范围为0到255的整数。

在 3.3 版更改: 也接受范围为0到255的整数作为子序列。

bytes.rindex(sub[, start[, end]])
bytearray.rindex(sub[, start[, end]])

rfind(),但当没有找到子序列 sub 时提高 ValueError

要搜索的子序列可以是任何 bytes-like object 或范围为0到255的整数。

在 3.3 版更改: 也接受范围为0到255的整数作为子序列。

bytes.rpartition(sep)
bytearray.rpartition(sep)

拆分 sep 最后一次出现的序列,并返回包含分隔符之前的部分,分隔符和分隔符后面的部分的3元组。如果找不到分隔符,则返回包含原始序列副本的3元组,后跟两个空字节或bytearray对象。

要搜索的分隔符可以是任何 bytes-like object

bytes.startswith(prefix[, start[, end]])
bytearray.startswith(prefix[, start[, end]])

如果二进制数据以指定的 prefix 开头,则返回 True,否则返回 Falseprefix 也可以是一个元组的前缀寻找。使用可选的 start,测试从该位置开始。使用可选的 end,停止在该位置的比较。

要搜索的前缀可以是任何 bytes-like object

bytes.translate(table, delete=b'')
bytearray.translate(table, delete=b'')

返回字节或bytearray对象的副本,其中删除了可选参数 delete 中发生的所有字节,剩余的字节已通过给定的转换表映射,该转换表必须是长度为256的字节对象。

您可以使用 bytes.maketrans() 方法来创建转换表。

对于只删除字符的翻译,将 table 参数设置为 None:

>>> b'read this short text'.translate(None, b'aeiou')
b'rd ths shrt txt'

在 3.6 版更改: 现在支持 delete 作为关键字参数。

字节和bytearray对象的以下方法具有默认行为,它们假定使用ASCII兼容的二进制格式,但仍然可以通过传递适当的参数与任意二进制数据一起使用。请注意,本节中的所有bytearray方法都是 not 操作,而是生成新对象。

bytes.center(width[, fillbyte])
bytearray.center(width[, fillbyte])

返回以长度为 width 的序列为中心的对象的副本。填充使用指定的 fillbyte (默认为ASCII空格)完成。对于 bytes 对象,如果 width 小于或等于 len(s),则返回原始序列。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.ljust(width[, fillbyte])
bytearray.ljust(width[, fillbyte])

返回长度为 width 的序列中左对齐的对象的副本。填充使用指定的 fillbyte (默认为ASCII空格)完成。对于 bytes 对象,如果 width 小于或等于 len(s),则返回原始序列。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.lstrip([chars])
bytearray.lstrip([chars])

返回具有指定前导字节的序列的副本。 chars 参数是一个二进制序列,指定要删除的字节值集合 - 名称指的是此方法通常与ASCII字符一起使用的事实。如果省略或 Nonechars 参数默认为删除ASCII空格。 chars 参数不是前缀;相反,其值的所有组合都被去除:

>>> b'   spacious   '.lstrip()
b'spacious   '
>>> b'www.example.com'.lstrip(b'cmowz.')
b'example.com'

要移除的字节值的二进制序列可以是任何 bytes-like object

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.rjust(width[, fillbyte])
bytearray.rjust(width[, fillbyte])

返回在长度为 width 的序列中右对齐的对象的副本。填充使用指定的 fillbyte (默认为ASCII空格)完成。对于 bytes 对象,如果 width 小于或等于 len(s),则返回原始序列。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.rsplit(sep=None, maxsplit=-1)
bytearray.rsplit(sep=None, maxsplit=-1)

将二进制序列拆分为相同类型的子序列,使用 sep 作为定界符字符串。如果给出 maxsplit,则最多进行 maxsplit 分裂,rightmost 分裂。如果未指定 sepNone,则仅由ASCII空格组成的任何子序列是分隔符。除了从右边分开,rsplit() 表现得像 split(),这将在下面详细描述。

bytes.rstrip([chars])
bytearray.rstrip([chars])

返回具有指定尾随字节的序列的副本。 chars 参数是一个二进制序列,指定要删除的字节值集合 - 名称指的是此方法通常与ASCII字符一起使用的事实。如果省略或 Nonechars 参数默认为删除ASCII空格。 chars 参数不是后缀;相反,其值的所有组合都被去除:

>>> b'   spacious   '.rstrip()
b'   spacious'
>>> b'mississippi'.rstrip(b'ipz')
b'mississ'

要移除的字节值的二进制序列可以是任何 bytes-like object

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.split(sep=None, maxsplit=-1)
bytearray.split(sep=None, maxsplit=-1)

将二进制序列拆分为相同类型的子序列,使用 sep 作为定界符字符串。如果给定 maxsplit 且非负,则最多进行 maxsplit 分割(因此,列表将具有至多 maxsplit+1 个元素)。如果没有指定 maxsplit 或者是 -1,则对分割数量没有限制(进行所有可能的分割)。

如果给出 sep,则连续分隔符不被分组在一起并且被认为定界空子序列(例如,b'1,,2'.split(b',') 返回 [b'1', b'', b'2'])。 sep 参数可以由多字节序列组成(例如,b'1<>2<>3'.split(b'<>') 返回 [b'1', b'2', b'3'])。使用指定的分隔符拆分空序列会根据要拆分的对象的类型返回 [b''][bytearray(b'')]sep 参数可以是任何 bytes-like object

例如:

>>> b'1,2,3'.split(b',')
[b'1', b'2', b'3']
>>> b'1,2,3'.split(b',', maxsplit=1)
[b'1', b'2,3']
>>> b'1,2,,3,'.split(b',')
[b'1', b'2', b'', b'3', b'']

如果未指定 sep 或为 None,则应用不同的分割算法:连续ASCII空格的运行被视为单个分隔符,如果序列具有前导或尾随空格,则结果将在开始或结束处不包含空字符串。因此,拆分空序列或仅由ASCII空格组成但不带指定分隔符的序列返回 []

例如:

>>> b'1 2 3'.split()
[b'1', b'2', b'3']
>>> b'1 2 3'.split(maxsplit=1)
[b'1', b'2 3']
>>> b'   1   2   3   '.split()
[b'1', b'2', b'3']
bytes.strip([chars])
bytearray.strip([chars])

返回具有指定前导和尾随字节的序列的副本。 chars 参数是一个二进制序列,指定要删除的字节值集合 - 名称指的是此方法通常与ASCII字符一起使用的事实。如果省略或 Nonechars 参数默认为删除ASCII空格。 chars 参数不是前缀或后缀;相反,其值的所有组合都被去除:

>>> b'   spacious   '.strip()
b'spacious'
>>> b'www.example.com'.strip(b'cmowz.')
b'example'

要移除的字节值的二进制序列可以是任何 bytes-like object

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

以下对字节和bytearray对象的方法假定使用ASCII兼容的二进制格式,不应该应用于任意二进制数据。请注意,本节中的所有bytearray方法都是 not 操作,而是生成新对象。

bytes.capitalize()
bytearray.capitalize()

返回一个序列的副本,每个字节被解释为ASCII字符,第一个字节大写,其余部分为小写。非ASCII字节值不变地传递。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.expandtabs(tabsize=8)
bytearray.expandtabs(tabsize=8)

返回序列的副本,其中所有ASCII制表符由一个或多个ASCII空格替换,具体取决于当前列和给定的制表符大小。标签位置每个 tabsize 字节出现(默认值为8,在0,8,16列等位置给出标签位置)。要扩展序列,当前列设置为零,并且逐个字节检查序列。如果该字节是ASCII制表符字符(b'\t'),则在结果中插入一个或多个空格字符,直到当前列等于下一个制表符位置。 (不复制制表符字符本身。)如果当前字节是ASCII换行符(b'\n')或回车符(b'\r'),则复制它,当前列复位为零。任何其他字节值被不变地复制,并且当前列被增加1,而不管在打印时如何表示字节值:

>>> b'01\t012\t0123\t01234'.expandtabs()
b'01      012     0123    01234'
>>> b'01\t012\t0123\t01234'.expandtabs(4)
b'01  012 0123    01234'

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.isalnum()
bytearray.isalnum()

如果序列中的所有字节都是字母ASCII字符或ASCII十进制数字,并且序列不为空,则返回true,否则返回false。字母ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。 ASCII十进制数字是序列 b'0123456789' 中的那些字节值。

例如:

>>> b'ABCabc1'.isalnum()
True
>>> b'ABC abc1'.isalnum()
False
bytes.isalpha()
bytearray.isalpha()

如果序列中的所有字节都是字母ASCII字符并且序列不为空,则返回true,否则返回false。字母ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

例如:

>>> b'ABCabc'.isalpha()
True
>>> b'ABCabc1'.isalpha()
False
bytes.isdigit()
bytearray.isdigit()

如果序列中的所有字节都是ASCII十进制数字,并且序列不为空,则返回true,否则返回false。 ASCII十进制数字是序列 b'0123456789' 中的那些字节值。

例如:

>>> b'1234'.isdigit()
True
>>> b'1.23'.isdigit()
False
bytes.islower()
bytearray.islower()

如果序列中至少有一个小写ASCII字符,并且没有大写ASCII字符,则返回true,否则返回false。

例如:

>>> b'hello world'.islower()
True
>>> b'Hello world'.islower()
False

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

bytes.isspace()
bytearray.isspace()

如果序列中的所有字节都是ASCII空格,并且序列不为空,则返回true,否则返回false。 ASCII空格字符是序列 b' \t\n\r\x0b\f' (空格,制表符,换行符,回车符,垂直制表符,换页符)中的那些字节值。

bytes.istitle()
bytearray.istitle()

如果序列是ASCII标题,并且序列不为空,则返回true,否则返回false。有关“titlecase”定义的更多细节,请参阅 bytes.title()

例如:

>>> b'Hello World'.istitle()
True
>>> b'Hello world'.istitle()
False
bytes.isupper()
bytearray.isupper()

如果序列中至少有一个大写字母ASCII字符,并且没有小写ASCII字符,则返回true,否则返回false。

例如:

>>> b'HELLO WORLD'.isupper()
True
>>> b'Hello world'.isupper()
False

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

bytes.lower()
bytearray.lower()

返回所有大写ASCII字符转换为其对应的小写副本的序列副本。

例如:

>>> b'Hello World'.lower()
b'hello world'

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.splitlines(keepends=False)
bytearray.splitlines(keepends=False)

返回二进制序列中的行的列表,在ASCII行边界处断开。此方法使用 universal newlines 方法分割线。换行符不包括在结果列表中,除非给定 keepends 并且为true。

例如:

>>> b'ab c\n\nde fg\rkl\r\n'.splitlines()
[b'ab c', b'', b'de fg', b'kl']
>>> b'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
[b'ab c\n', b'\n', b'de fg\r', b'kl\r\n']

与给定分隔符字符串 sep 时的 split() 不同,此方法为空字符串返回空列表,并且终端行断开不会产生额外行:

>>> b"".split(b'\n'), b"Two lines\n".split(b'\n')
([b''], [b'Two lines', b''])
>>> b"".splitlines(), b"One line\n".splitlines()
([], [b'One line'])
bytes.swapcase()
bytearray.swapcase()

返回序列的副本,所有小写ASCII字符转换为其对应的大写副本,反之亦然。

例如:

>>> b'Hello World'.swapcase()
b'hELLO wORLD'

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

str.swapcase() 不同,它始终是 bin.swapcase().swapcase() == bin 的二进制版本。案例转换在ASCII中是对称的,即使对于任意Unicode代码点通常也不是真的。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.title()
bytearray.title()

返回二进制序列的标题化版本,其中单词以大写ASCII字符开头,其余字符为小写。未编写的字节值保持不变。

例如:

>>> b'Hello world'.title()
b'Hello World'

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。所有其他字节值都未设置。

该算法使用单词的简单的语言无关定义作为连续字母的组。该定义在许多上下文中工作,但它意味着收缩和占有的撇号形成词边界,这可能不是期望的结果:

>>> b"they're bill's friends from the UK".title()
b"They'Re Bill'S Friends From The Uk"

可以使用正则表达式构造撇号的解决方法:

>>> import re
>>> def titlecase(s):
...     return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?",
...                   lambda mo: mo.group(0)[0:1].upper() +
...                              mo.group(0)[1:].lower(),
...                   s)
...
>>> titlecase(b"they're bill's friends.")
b"They're Bill's Friends."

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.upper()
bytearray.upper()

返回具有所有小写ASCII字符的序列的副本,转换为它们对应的大写副本。

例如:

>>> b'Hello World'.upper()
b'HELLO WORLD'

小写ASCII字符是序列 b'abcdefghijklmnopqrstuvwxyz' 中的那些字节值。大写ASCII字符是序列 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的那些字节值。

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

bytes.zfill(width)
bytearray.zfill(width)

返回剩余的填充ASCII b'0' 数字的序列的副本,以使长度为 width 的序列。前导符号前缀(b'+'/b'-' 通过插入填充 after 符号字符而不是之前处理。对于 bytes 对象,如果 width 小于或等于 len(seq),则返回原始序列。

例如:

>>> b"42".zfill(5)
b'00042'
>>> b"-42".zfill(5)
b'-0042'

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

4.8.4. printf 样式字节格式化

注解

这里描述的格式化操作展示了导致多个常见错误(例如未能正确地显示元组和字典)的各种怪癖。如果正在打印的值可能是元组或字典,请将其包装在元组中。

字节对象(bytes/bytearray)有一个独特的内置操作:% 运算符(模)。这也称为字节 formattinginterpolation 运算符。给定 format % values (其中 format 是字节对象),format 中的 % 转换规范被 values 的零个或多个元素替换。效果类似于在C语言中使用 sprintf()

如果 format 需要单个参数,则 values 可以是单个非元组对象。 [5] 否则,values 必须是一个元组,其具有由格式bytes对象或单个映射对象(例如,字典)指定的项目数。

转换说明符包含两个或多个字符,并具有以下组件,它们必须按此顺序发生:

  1. '%' 字符,它标记了说明符的开始。

  2. 映射键(可选),由括号中的字符序列(例如,(somename))组成。

  3. 转换标志(可选),会影响某些转换类型的结果。

  4. 最小字段宽度(可选)。如果指定为 '*' (星号),则从 values 中元组的下一个元素读取实际宽度,要转换的对象在最小字段宽度和可选精度之后。

  5. 精度(可选),以 '.' (点)形式给出,后跟精度。如果指定为 '*' (星号),则从 values 中的元组的下一个元素读取实际精度,并且要转换的值在精度之后。

  6. 长度修饰符(可选)。

  7. 转换类型。

当右参数是字典(或其他映射类型)时,字节对象 must 中的格式包括在紧接在 '%' 字符之后插入的字典中的括号映射键。映射键从映射中选择要格式化的值。例如:

>>> print(b'%(language)s has %(number)03d quote types.' %
...       {b'language': b"Python", b"number": 2})
b'Python has 002 quote types.'

在这种情况下,在格式中不会出现 * 说明符(因为它们需要顺序参数列表)。

转换标志字符有:

含义

'#'

值转换将使用“备用形式”(以下定义)。

'0'

转换将被零填充为数值。

'-'

转换后的值将被调整(如果同时给出 '0' 转换,则覆盖 '0' 转换)。

' '

(空格)空格应留在由带符号的转换产生的正数(或空字符串)之前。

'+'

符号字符('+''-')将在转换之前(覆盖“空格”标志)。

长度修饰符(hlL)可以存在,但是被忽略,因为对于Python不是必需的。 %ld%d 相同。

转换类型有:

转换

含义

笔记

'd'

有符号整数十进制。

 

'i'

有符号整数十进制。

 

'o'

带符号的八进制值。

(1)

'u'

过时类型 - 它与 'd' 相同。

(8)

'x'

带符号的十六进制(小写)。

(2)

'X'

带符号的十六进制(大写)。

(2)

'e'

浮点指数格式(小写)。

(3)

'E'

浮点指数格式(大写)。

(3)

'f'

浮点十进制格式。

(3)

'F'

浮点十进制格式。

(3)

'g'

浮点格式。如果指数小于-4或不小于精度,则使用小写指数格式,否则使用十进制格式。

(4)

'G'

浮点格式。如果指数小于-4或不小于精度,则使用大写指数格式,否则使用十进制格式。

(4)

'c'

单字节(接受整数或单字节对象)。

 

'b'

字节(跟随 缓冲协议 或具有 __bytes__() 的任何对象)。

(5)

's'

's''b' 的别名,应该只用于Python2/3代码库。

(6)

'a'

字节(使用 repr(obj).encode('ascii','backslashreplace) 转换任何Python对象)。

(5)

'r'

'r''a' 的别名,应该只用于Python2/3代码库。

(7)

'%'

不转换参数,在结果中产生 '%' 字符。

 

笔记:

  1. 如果结果的前导字符不是零,则替换形式使得前导零('0')插入在左侧填充和数字的格式化之间。

  2. 如果结果的前导字符不是零,则替代形式导致前导 '0x''0X' (取决于是否使用 'x''X' 格式)插入左侧填充和数字的格式化之间。

  3. 备用形式使结果始终包含小数点,即使后面没有数字。

    精度确定小数点后的位数,默认为6。

  4. 替代形式导致结果始终包含小数点,并且后续零不会被删除,因为它们将是。

    精度确定小数点前后的有效数字的数量,默认为6。

  5. 如果precision是 N,则输出将被截断为 N 个字符。

  6. b'%s' 已弃用,但不会在3.x系列期间删除。

  7. b'%r' 已弃用,但不会在3.x系列期间删除。

  8. PEP 237

注解

这个方法的bytearray版本的 not 操作就在 - 它总是产生一个新的对象,即使没有改变。

参见

PEP 461

3.5 新版功能.

4.8.5. 内存视图

memoryview 对象允许Python代码访问支持 缓冲协议 而不进行复制的对象的内部数据。

class memoryview(obj)

创建引用 objmemoryviewobj 必须支持缓冲区协议。支持缓冲协议的内置对象包括 bytesbytearray

memoryview 具有 element 的概念,element 是由始发对象 obj 处理的原子存储器单元。对于许多简单类型(例如 bytesbytearray),元素是单个字节,但是其他类型(例如 array.array)可能具有较大的元素。

len(view) 等于 tolist 的长度。如果 view.ndim = 0,长度为1.如果 view.ndim = 1,长度等于视图中的元素数。对于较高的维度,长度等于视图的嵌套列表表示的长度。 itemsize 属性将为您提供单个元素中的字节数。

memoryview 支持切片和索引以公开其数据。一维切片将产生子视图:

>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'

如果 formatstruct 模块的原生格式说明符之一,那么也支持使用整数或整数元组的索引,并返回具有正确类型的单个 element。一维内存视图可以用整数或整数元组索引。多维内存视图可以用完全是 ndim 整数的元组索引,其中 ndim 是维数。零维存储器视图可以用空元组索引。

这是一个非字节格式的示例:

>>> import array
>>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444])
>>> m = memoryview(a)
>>> m[0]
-11111111
>>> m[-1]
44444444
>>> m[::2].tolist()
[-11111111, -33333333]

如果基础对象是可写的,则memoryview支持一维片分配。不允许调整大小:

>>> data = bytearray(b'abcefg')
>>> v = memoryview(data)
>>> v.readonly
False
>>> v[0] = ord(b'z')
>>> data
bytearray(b'zbcefg')
>>> v[1:4] = b'123'
>>> data
bytearray(b'z123fg')
>>> v[2:3] = b'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: memoryview assignment: lvalue and rvalue have different structures
>>> v[2:6] = b'spam'
>>> data
bytearray(b'z1spam')

具有格式“B”,“b”或“c”的散列(只读)类型的一维存储器视图也是可哈希的。散列定义为 hash(m) == hash(m.tobytes()):

>>> v = memoryview(b'abcefg')
>>> hash(v) == hash(b'abcefg')
True
>>> hash(v[2:4]) == hash(b'ce')
True
>>> hash(v[::-2]) == hash(b'abcefg'[::-2])
True

在 3.3 版更改: 一维内存视图现在可以切片。具有格式“B”,“b”或“c”的一维存储器查看现在是可哈希的。

在 3.4 版更改: memoryview现在自动注册到 collections.abc.Sequence

在 3.5 版更改: memoryviews现在可以用整数的元组索引。

memoryview 有几种方法:

__eq__(exporter)

如果存储器视图和 PEP 3118 导出器的形状相同,并且当使用 struct 语法解释操作数的相应格式代码时,所有相应的值相等,则存储器视图和 PEP 3118 导出器是相等的。

对于 tolist() 当前支持的 struct 格式字符串的子集,如果 v.tolist() == w.tolist(),则 vw 相等:

>>> import array
>>> a = array.array('I', [1, 2, 3, 4, 5])
>>> b = array.array('d', [1.0, 2.0, 3.0, 4.0, 5.0])
>>> c = array.array('b', [5, 3, 1])
>>> x = memoryview(a)
>>> y = memoryview(b)
>>> x == a == y == b
True
>>> x.tolist() == a.tolist() == y.tolist() == b.tolist()
True
>>> z = y[::-2]
>>> z == c
True
>>> z.tolist() == c.tolist()
True

如果 struct 模块不支持任一格式字符串,那么对象将始终比较为不等(即使格式字符串和缓冲区内容相同):

>>> from ctypes import BigEndianStructure, c_long
>>> class BEPoint(BigEndianStructure):
...     _fields_ = [("x", c_long), ("y", c_long)]
...
>>> point = BEPoint(100, 200)
>>> a = memoryview(point)
>>> b = memoryview(point)
>>> a == point
False
>>> a == b
False

注意,与浮点数一样,v is w 对内存视图对象执行 not 表示 v == w

在 3.3 版更改: 以前的版本比较了原始内存,忽略了项目格式和逻辑数组结构。

tobytes()

以字节形式返回缓冲区中的数据。这相当于在内存视图上调用 bytes 构造函数。

>>> m = memoryview(b"abc")
>>> m.tobytes()
b'abc'
>>> bytes(m)
b'abc'

对于非连续数组,结果等于扁平列表表示,其中所有元素都转换为字节。 tobytes() 支持所有格式字符串,包括不在 struct 模块语法中的字符串。

hex()

返回包含缓冲区中每个字节的两个十六进制数字的字符串对象。

>>> m = memoryview(b"abc")
>>> m.hex()
'616263'

3.5 新版功能.

tolist()

以元素列表的形式返回缓冲区中的数据。

>>> memoryview(b'abc').tolist()
[97, 98, 99]
>>> import array
>>> a = array.array('d', [1.1, 2.2, 3.3])
>>> m = memoryview(a)
>>> m.tolist()
[1.1, 2.2, 3.3]

在 3.3 版更改: tolist() 现在支持 struct 模块语法中的所有单字符原生格式以及多维表示。

release()

释放由memoryview对象公开的底层缓冲区。许多对象在视图被持有时采取特殊动作(例如,bytearray 将暂时禁止调整大小);因此,调用release()方便快速删除这些限制(并释放任何悬空资源)。

调用此方法后,对视图的任何进一步操作都会引发 ValueError (除了 release() 本身,可以多次调用):

>>> m = memoryview(b'abc')
>>> m.release()
>>> m[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object

使用 with 语句,上下文管理协议可以用于类似的效果:

>>> with memoryview(b'abc') as m:
...     m[0]
...
97
>>> m[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object

3.2 新版功能.

cast(format[, shape])

将memoryview转换为新的格式或形状。 shape 默认为 [byte_length//new_itemsize],这意味着结果视图将是一维的。返回值是一个新的内存视图,但缓冲区本身不被复制。支持的cast是1D - > C-contiguous 和C-contiguous - > 1D。

目标格式限制为 struct 语法中的单个元素本机格式。其中一种格式必须是字节格式(’B’,’b’或’c’)。结果的字节长度必须与原始长度相同。

将1D/long转换为1D/无符号字节:

>>> import array
>>> a = array.array('l', [1,2,3])
>>> x = memoryview(a)
>>> x.format
'l'
>>> x.itemsize
8
>>> len(x)
3
>>> x.nbytes
24
>>> y = x.cast('B')
>>> y.format
'B'
>>> y.itemsize
1
>>> len(y)
24
>>> y.nbytes
24

将1D/无符号字节转换为1D/char:

>>> b = bytearray(b'zyz')
>>> x = memoryview(b)
>>> x[0] = b'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: memoryview: invalid value for format "B"
>>> y = x.cast('c')
>>> y[0] = b'a'
>>> b
bytearray(b'ayz')

将1D/字节转换为3D/int到1D/signed char:

>>> import struct
>>> buf = struct.pack("i"*12, *list(range(12)))
>>> x = memoryview(buf)
>>> y = x.cast('i', shape=[2,2,3])
>>> y.tolist()
[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
>>> y.format
'i'
>>> y.itemsize
4
>>> len(y)
2
>>> y.nbytes
48
>>> z = y.cast('b')
>>> z.format
'b'
>>> z.itemsize
1
>>> len(z)
48
>>> z.nbytes
48

将1D/unsigned char转换为2D/unsigned long:

>>> buf = struct.pack("L"*6, *list(range(6)))
>>> x = memoryview(buf)
>>> y = x.cast('L', shape=[2,3])
>>> len(y)
2
>>> y.nbytes
48
>>> y.tolist()
[[0, 1, 2], [3, 4, 5]]

3.3 新版功能.

在 3.5 版更改: 转换为字节视图时,源格式不再受限制。

还有几个只读属性可用:

obj

内存视图的基础对象:

>>> b  = bytearray(b'xyz')
>>> m = memoryview(b)
>>> m.obj is b
True

3.3 新版功能.

nbytes

nbytes == product(shape) * itemsize == len(m.tobytes())。这是数组在连续表示中使用的空间量(以字节为单位)。它不一定等于len(m):

>>> import array
>>> a = array.array('i', [1,2,3,4,5])
>>> m = memoryview(a)
>>> len(m)
5
>>> m.nbytes
20
>>> y = m[::2]
>>> len(y)
3
>>> y.nbytes
12
>>> len(y.tobytes())
12

多维数组:

>>> import struct
>>> buf = struct.pack("d"*12, *[1.5*x for x in range(12)])
>>> x = memoryview(buf)
>>> y = x.cast('d', shape=[3,4])
>>> y.tolist()
[[0.0, 1.5, 3.0, 4.5], [6.0, 7.5, 9.0, 10.5], [12.0, 13.5, 15.0, 16.5]]
>>> len(y)
3
>>> y.nbytes
96

3.3 新版功能.

readonly

一个bool指示内存是否为只读。

format

一个字符串,包含视图中每个元素的格式(在 struct 模块样式中)。可以从具有任意格式字符串的导出器创建存储器视图,但是一些方法(例如 tolist())被限制为本地单元素格式。

在 3.3 版更改: 格式 'B' 现在根据struct模块语法处理。这意味着 memoryview(b'abc')[0] == b'abc'[0] == 97

itemsize

memoryview的每个元素的字节大小:

>>> import array, struct
>>> m = memoryview(array.array('H', [32000, 32001, 32002]))
>>> m.itemsize
2
>>> m[0]
32000
>>> struct.calcsize('H') == m.itemsize
True
ndim

一个整数,指示存储器表示的多维数组的维数。

shape

ndim 的长度的整数的元组给出存储器的形状作为N维数组。

在 3.3 版更改: 当ndim = 0时,使用空元组代替 None

strides

ndim 长度的整数的元组,以字节为单位来访问数组的每个维度的每个元素。

在 3.3 版更改: 当ndim = 0时,使用空元组代替 None

suboffsets

用于PIL类型的数组。该值仅供参考。

c_contiguous

指示存储器是否为C-contiguous 的布尔。

3.3 新版功能.

f_contiguous

一个bool指示内存是否为Fortran contiguous

3.3 新版功能.

contiguous

一个bool指示内存是否为 contiguous

3.3 新版功能.

4.9. 设置类型— setfrozenset

set 对象是不同 hashable 对象的无序集合。常用的应用包括成员资格测试,从序列中删除重复,以及计算数学运算,如交集,并集,差分和对称差分。 (对于其他容器,请参阅内置的 dictlisttuple 类以及 collections 模块。)

像其他集合一样,集合支持 x in setlen(set)for x in set。作为无序集合,集合不记录元素位置或插入顺序。因此,集合不支持索引,切片或其他类似序列的行为。

目前有两种内置集类型,setfrozensetset 类型是可变的 - 可以使用诸如 add()remove() 的方法来改变内容。由于它是可变的,它没有哈希值,不能用作字典键或另一个集合的元素。 frozenset 类型是不可变的,hashable —它的内容在创建后不能被改变;它因此可以用作字典键或作为另一个集合的元素。

可以通过在大括号中放置逗号分隔的元素列表来创建非空集(不是frozensets),例如:{'jack', 'sjoerd'},以及 set 构造函数。

两个类的构造函数都工作相同:

class set([iterable])
class frozenset([iterable])

返回一个新的set或frozenset对象,其元素取自 iterable。集合的元素必须是 hashable。要表示集合集,内部集必须是 frozenset 对象。如果未指定 iterable,则返回新的空集。

setfrozenset 的实例提供以下操作:

len(s)

返回集合 ss 的基数)中的元素数。

x in s

测试 x 成为 s 的会员资格。

x not in s

测试 xs 成员资格。

isdisjoint(other)

如果集合没有与 other 共同的元素,则返回 True。当且仅当它们的交集是空集时,集合是不相交的。

issubset(other)
set <= other

测试集合中的每个元素是否都在 other 中。

set < other

测试集合是否是 other 的正确子集,即 set <= other and set != other

issuperset(other)
set >= other

测试 other 中的每个元素是否在集合中。

set > other

测试集合是否是 other 的正确超集,即 set >= other and set != other

union(*others)
set | other | ...

返回一个新集合,其中包含集合中的元素和所有其他元素。

intersection(*others)
set & other & ...

返回一个包含该集合和所有其他公共元素的新集合。

difference(*others)
set - other - ...

返回一个新集合,其中的集合中的元素不在其他人。

symmetric_difference(other)
set ^ other

返回一个新集合,其中包含集合或 other 中的元素,但不能同时包含两者。

copy()

返回一个包含 s 的浅拷贝的新集合。

注意,非操作符版本的 union()intersection()difference()symmetric_difference()issubset()issuperset() 方法将接受任何可迭代作为参数。相比之下,它们的基于运算符的对等体需要它们的参数是集合。这排除了容易出错的结构,如 set('abc') & 'cbs',有利于更易读的 set('abc').intersection('cbs')

setfrozenset 都支持设置比较。当且仅当每个集合的每个元素都包含在另一个(每个都是另一个的子集)时,两个集合是相等的。一组是小于另一组当且仅当该第一组是第二组的一个子集(为一个子集,但是不相等)。一组比另一组更大当且仅当该第一组是第二组的一个适当的超集(是一个超集,但是不相等)。

基于 set 的成员将 set 的实例与 frozenset 的实例进行比较。例如,set('abc') == frozenset('abc') 返回 Trueset('abc') in set([frozenset('abc')]) 也如此。

子集和等式比较不推广到总排序函数。例如,任何两个非空的不相交集不相等,并且不是彼此的子集,因此以下的 all 返回 Falsea<ba==ba>b

由于集合仅定义部分排序(子集关系),因此 list.sort() 方法的输出未定义为集合列表。

设置元素,如字典键,必须是 hashable

set 实例与 frozenset 混合的二进制操作返回第一个操作数的类型。例如:frozenset('ab') | set('bc') 返回 frozenset 的实例。

下表列出了不适用于 frozenset 的不可变实例的 set 可用操作:

update(*others)
set |= other | ...

更新集,添加所有其他元素。

intersection_update(*others)
set &= other & ...

更新集合,只保留在它和所有其他的元素。

difference_update(*others)
set -= other | ...

更新集合,删除其他人中找到的元素。

symmetric_difference_update(other)
set ^= other

更新集合,仅保留在任一集合中找到的元素,但不在两者中。

add(elem)

将元素 elem 添加到集合。

remove(elem)

从集合中删除元素 elem。如果 elem 不包含在集合中,则提高 KeyError

discard(elem)

从集合中删除元素 elem (如果存在)。

pop()

从集合中删除并返回任意元素。如果集合为空,则提升 KeyError

clear()

从集合中删除所有元素。

注意,非操作符版本的 update()intersection_update()difference_update()symmetric_difference_update() 方法将接受任何可迭代作为参数。

注意,__contains__()remove()discard() 方法的 elem 参数可以是一个集合。为了支持搜索等效的模糊搜索,elem 集在搜索期间被暂时地改变,然后被恢复。在搜索期间,elem 集不应被读取或变异,因为它没有有意义的值。

4.10. 映射类型— dict

mapping 对象将 hashable 值映射到任意对象。映射是可变对象。目前只有一种标准映射类型,即 dictionary。 (对于其他容器,请参阅内置的 listsettuple 类以及 collections 模块。)

字典的键是 almost 任意值。不是 hashable 的值,即包含列表,字典或其他可变类型(通过值而不是对象标识进行比较)的值不能用作键。用于键的数字类型遵守用于数字比较的正常规则:如果两个数字比较相等(例如 11.0),则它们可以互换地用于索引相同的字典条目。 (但是请注意,由于计算机存储浮点数作为近似值,因此使用它们作为字典键通常是不明智的。)

可以通过在大括号中放置以逗号分隔的 key: value 对的列表来创建字典,例如:{'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'},或由 dict 构造函数。

class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)

返回从可选的位置参数和可能为空的一组关键字参数初始化的新字典。

如果没有给出位置参数,则创建一个空字典。如果给定了位置参数,并且它是映射对象,则使用与映射对象相同的键值对创建字典。否则,位置参数必须是 iterable 对象。迭代器中的每个项本身必须是具有两个对象的迭代。每个项目的第一个对象成为新字典中的键,第二个对象的对应值。如果键多次出现,则该键的最后一个值变为新字典中的相应值。

如果给出关键字参数,则将关键字参数及其值添加到从位置参数创建的字典中。如果要添加的键已经存在,则来自关键字参数的值将替换位置参数中的值。

为了说明,以下示例都返回等于 {"one": 1, "two": 2, "three": 3} 的字典:

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

提供如第一个示例中的关键字参数仅适用于有效的Python标识符的键。否则,可以使用任何有效的密钥。

这些是字典支持的操作(因此,自定义映射类型也应该支持):

len(d)

返回字典 d 中的项目数。

d[key]

用密钥 key 返回 d 的项目。如果 key 不在地图中,则引发 KeyError

如果dict的一个子类定义了一个方法 __missing__()key 不存在,则 d[key] 操作以键 key 作为参数调用该方法。 d[key] 操作然后返回或提出 __missing__(key) 调用返回或产生的任何内容。没有其他操作或方法调用 __missing__()。如果未定义 __missing__(),则产生 KeyError__missing__() 必须是方法;它不能是一个实例变量:

>>> class Counter(dict):
...     def __missing__(self, key):
...         return 0
>>> c = Counter()
>>> c['red']
0
>>> c['red'] += 1
>>> c['red']
1

上面的示例显示了 collections.Counter 实施的一部分。 collections.defaultdict 使用不同的 __missing__ 方法。

d[key] = value

d[key] 设置为 value

del d[key]

d 中删除 d[key]。如果 key 不在地图中,则引发 KeyError

key in d

如果 d 具有密钥 key,则返回 True,否则返回 False

key not in d

相当于 not key in d

iter(d)

在字典的键上返回一个迭代器。这是 iter(d.keys()) 的一个快捷方式。

clear()

从字典中删除所有项目。

copy()

返回字典的浅拷贝。

classmethod fromkeys(seq[, value])

使用 seq 中的键创建新字典,并将值设置为 value

fromkeys() 是返回一个新字典的类方法。 value 默认为 None

get(key[, default])

如果 key 在字典中,则返回 key 的值,否则返回 default。如果没有给出 default,它默认为 None,因此这种方法不会产生 KeyError

items()

返回字典项目((key, value) 对)的新视图。见 视图对象的文档

keys()

返回字典键的新视图。见 视图对象的文档

pop(key[, default])

如果 key 在字典中,请删除它并返回其值,否则返回 default。如果没有给出 default 并且 key 不在字典中,则引发 KeyError

popitem()

从字典中删除并返回任意 (key, value) 对。

popitem() 对于在集合算法中经常使用的字典进行破坏性迭代是有用的。如果字典是空的,调用 popitem() 会产生一个 KeyError

setdefault(key[, default])

如果 key 在字典中,则返回其值。如果不是,插入 key 值为 default 并返回 defaultdefault 默认为 None

update([other])

使用 other 中的键/值对更新字典,覆盖现有键。返回 None

update() 接受另一个字典对象或键/值对的可迭代(作为元组或其他长度为二的迭代)。如果指定了关键字参数,则使用这些键/值对更新字典:d.update(red=1, blue=2)

values()

返回字典值的新视图。见 视图对象的文档

字典比较等于且仅当它们具有相同的 (key, value) 对。订单比较(’<’,’<=’,’> =’,’>’)提高 TypeError

参见

types.MappingProxyType 可用于创建 dict 的只读视图。

4.10.1. 字典视图对象

dict.keys()dict.values()dict.items() 返回的对象是 查看对象。它们提供了对字典条目的动态视图,这意味着当字典更改时,视图反映这些更改。

可以迭代字典视图以生成其各自的数据,并支持成员资格测试:

len(dictview)

返回字典中的条目数。

iter(dictview)

在字典中的键,值或项(表示为 (key, value) 的元组)上返回一个迭代器。

键和值以任意顺序迭代,这是非随机的,随着Python实现而变化,并且取决于字典的插入和删除历史。如果键,值和项视图被迭代,没有对字典的中间修改,项的顺序将直接对应。这允许使用 zip()pairs = zip(d.values(), d.keys()) 创建 (value, key) 对。另一种创建相同列表的方法是 pairs = [(v, k) for (k, v) in d.items()]

在添加或删除字典中的条目时迭代视图可能会导致 RuntimeError 或无法遍历所有条目。

x in dictview

返回 True 如果 x 在底层字典的键,值或项目(在后一种情况下,x 应该是一个 (key, value) 元组)。

键视图是设置的,因为它们的条目是唯一的和哈希的。如果所有值都是哈希的,那么 (key, value) 对是唯一的和哈希的,那么项目视图也是类似的。 (值视图不被视为类集,因为条目通常不是唯一的。)对于类似集合的视图,为抽象基类 collections.abc.Set 定义的所有操作都可用(例如,==<^)。

字典视图用法的示例:

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()

>>> # iteration
>>> n = 0
>>> for val in values:
...     n += val
>>> print(n)
504

>>> # keys and values are iterated over in the same order
>>> list(keys)
['eggs', 'bacon', 'sausage', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['spam', 'bacon']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}
>>> keys ^ {'sausage', 'juice'}
{'juice', 'sausage', 'bacon', 'spam'}

4.11. 上下文管理器类型

Python的 with 语句支持由上下文管理器定义的运行时上下文的概念。这是使用一对方法实现的,这些方法允许用户定义的类定义在语句体执行之前输入的运行时上下文,并在语句结束时退出:

contextmanager.__enter__()

输入运行时上下文并返回此对象或与运行时上下文相关的另一个对象。此方法返回的值使用此上下文管理器绑定到 with 语句的 as 子句中的标识符。

返回自身的上下文管理器的示例是 file object。文件对象从__enter__()返回自己,以允许 open() 用作 with 语句中的上下文表达式。

返回相关对象的上下文管理器的示例是 decimal.localcontext() 返回的。这些管理器将活动十进制上下文设置为原始十进制上下文的副本,然后返回副本。这允许对 with 语句的主体中的当前十进制上下文进行更改,而不影响 with 语句之外的代码。

contextmanager.__exit__(exc_type, exc_val, exc_tb)

退出运行时上下文并返回一个布尔标志,指示是否应该抑制发生的任何异常。如果在执行 with 语句的主体时发生异常,则参数包含异常类型,值和回溯信息。否则,所有三个参数都是 None

从此方法返回真值将导致 with 语句抑制异常并继续执行紧跟在 with 语句之后的语句。否则,在此方法完成执行后,异常继续传播。在执行此方法期间发生的异常将会替换在 with 语句的主体中发生的任何异常。

传入的异常不应该被显式地重写 - 相反,这个方法应该返回一个false值来表示该方法成功完成,并且不想抑制提出的异常。这允许上下文管理代码容易地检测 __exit__() 方法是否实际上失败。

Python定义了几个上下文管理器来支持简单的线程同步,提示文件或其他对象的关闭,以及更简单地操作主动十进制算术上下文。特定类型在其实现上下文管理协议之外不被特别处理。有关示例,请参阅 contextlib 模块。

Python的 generatorcontextlib.contextmanager 装饰器提供了一种方便的方式来实现这些协议。如果生成器函数用 contextlib.contextmanager 装饰器装饰,它将返回实现必需的 __enter__()__exit__() 方法的上下文管理器,而不是由未修饰的生成器函数生成的迭代器。

请注意,在Python/C API中的Python对象的类型结构中没有任何这些方法的特定插槽。想要定义这些方法的扩展类型必须将它们作为普通的Python可访问方法提供。与设置运行时上下文的开销相比,单个类字典查找的开销可以忽略不计。

4.12. 其他内置类型

解释器支持几种其他类型的对象。其中大多数只支持一个或两个操作。

4.12.1. 模块

模块上唯一的特殊操作是属性访问:m.name,其中 m 是一个模块,name 访问 m 符号表中定义的名称。模块属性可以分配到。 (注意,import 语句严格来说不是对模块对象的操作; import foo 不需要存在名为 foo 的模块对象,而是需要一个名为 foo 的模块的(外部) definition。)

每个模块的特殊属性是 __dict__。这是包含模块的符号表的字典。修改这个字典实际上将改变模块的符号表,但不能直接赋值到 __dict__ 属性(你可以编写 m.__dict__['a'] = 1,它将 m.a 定义为 1,但是你不能写 m.__dict__ = {})。不建议直接修改 __dict__

解释器中内置的模块是这样写的:<module 'sys' (built-in)>。如果从文件加载,它们将被写为 <module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>

4.12.2. 类和类实例

请参阅 对象,值和类型类定义

4.12.3. 功能

函数对象由函数定义创建。对函数对象的唯一操作是调用它:func(argument-list)

有两种类型的函数对象:内置函数和用户定义函数。两者都支持相同的操作(调用函数),但实现是不同的,因此不同的对象类型。

有关详细信息,请参阅 函数定义

4.12.4. 方法

方法是使用属性符号调用的函数。有两种风格:内置方法(例如列表上的 append())和类实例方法。内置方法用支持它们的类型描述。

如果通过实例访问一个方法(在类命名空间中定义的函数),则会得到一个特殊对象:bound method (也称为 instance method)对象。当被调用时,它将 self 参数添加到参数列表中。绑定方法有两个特殊的只读属性:m.__self__ 是方法操作的对象,m.__func__ 是实现方法的函数。调用 m(arg-1, arg-2, ..., arg-n) 完全等同于调用 m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)

像函数对象一样,绑定方法对象支持获取任意属性。但是,由于方法属性实际上存储在底层函数对象(meth.__func__)上,因此不允许对绑定方法设置方法属性。尝试在方法上设置属性会导致生成 AttributeError。为了设置一个方法属性,您需要在底层函数对象上显式设置它:

>>> class C:
...     def method(self):
...         pass
...
>>> c = C()
>>> c.method.whoami = 'my name is method'  # can't set on the method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'method' object has no attribute 'whoami'
>>> c.method.__func__.whoami = 'my name is method'
>>> c.method.whoami
'my name is method'

有关详细信息,请参阅 标准类型层次结构

4.12.5. 代码对象

代码对象被实现用来表示“伪编译的”可执行的Python代码,例如函数体。它们与函数对象不同,因为它们不包含对其全局执行环境的引用。代码对象由内置的 compile() 函数返回,并且可以通过其 __code__ 属性从函数对象中提取。另请参阅 code 模块。

可以通过将代码对象(而不是源字符串)传递给 exec()eval() 内置函数来执行或评估代码对象。

有关详细信息,请参阅 标准类型层次结构

4.12.6. 类型对象

类型对象表示各种对象类型。对象的类型由内置函数 type() 访问。类型上没有特殊操作。标准模块 types 定义所有标准内置类型的名称。

类型写成这样:<class 'int'>

4.12.7. 空对象

此对象由不显式返回值的函数返回。它不支持特殊操作。只有一个空对象,名为 None (内置名称)。 type(None)() 产生相同的单例。

它被写为 None

4.12.8. 椭圆对象

此对象通常用于切片(参见 切片)。它不支持特殊操作。只有一个省略号对象,名为 Ellipsis (内置名称)。 type(Ellipsis)() 产生 Ellipsis 单体。

它被写为 Ellipsis...

4.12.9. 未实现的对象

当对象被要求对不支持的类型进行操作时,该对象从比较和二进制操作返回。有关详细信息,请参阅 比较。只有一个 NotImplemented 对象。 type(NotImplemented)() 产生单例实例。

它被写为 NotImplemented

4.12.10. 布尔值

布尔值是两个常量对象 FalseTrue。它们用于表示真值(虽然其他值也可以被认为是假或真)。在数值上下文中(例如,当用作算术运算符的参数时),它们分别表示整数0和1。内置函数 bool() 可用于将任何值转换为布尔值,如果该值可以解释为真值(请参见上文第 真值检验 部分)。

它们分别写为 FalseTrue

4.12.11. 内部对象

有关此信息,请参阅 标准类型层次结构。它描述堆栈框架对象,追溯对象和切片对象。

4.13. 特殊属性

实现向几个对象类型添加了一些特殊的只读属性,它们是相关的。其中一些不是由 dir() 内置函数报告的。

object.__dict__

用于存储对象(可写)属性的字典或其他映射对象。

instance.__class__

类实例所属的类。

class.__bases__

类对象的基类的元组。

definition.__name__

类,函数,方法,描述符或生成器实例的名称。

definition.__qualname__

qualified name 的类,函数,方法,描述符或生成器实例。

3.3 新版功能.

class.__mro__

此属性是在方法解析期间查找基类时考虑的类的元组。

class.mro()

此方法可以由元类覆盖以自定义其实例的方法解析顺序。它在类实例化时调用,其结果存储在 __mro__ 中。

class.__subclasses__()

每个类保存一个弱引用的直接子类的列表。此方法返回所有仍然活着的引用的列表。例:

>>> int.__subclasses__()
[<class 'bool'>]

脚注

[1]

关于这些特殊方法的更多信息可以在Python参考手册(基本定制)中找到。

[2]

因此,列表 [1, 2] 被认为等于 [1.0, 2.0],并且类似地对于元组。

[3]

他们必须有,因为解析器不能告诉操作数的类型。

[4](1, 2, 3, 4)

套用字符是一般类别属性为“Lu”(Letter,大写),“Ll”(Letter,小写字母)或“Lt”(Letter,titlecase)之一的字符。

[5](1, 2)

为了只格式化一个元组,你应该提供一个单元元组,其元素是要被格式化的元组。