Python内置类型补充

内置类型补充

下面是对Python解释器中内置的标准类型的一个补充。

Python的主要内置类型有数字、序列、映射、类、实例以及异常。

真值验证

任何对象都可以作为if或while的条件来做真值验证,以下情况均为假:

  • None
  • False
  • 数字零,类似0,0.0,0j等
  • 任意空序列,类似”,(),[]
  • 任意空映射,类似{}
  • 用户自定义类的实例,如果类定义了__bool__()或____len__()方法,当该方法返回数字0或布尔值False时

除了上述这些情况,其余情况都默认为True,因此许多不同类型的对象总为真值。

布尔运算符

下表是由优先级降序排列:

操作结果对应说明
x or yif x is false,then y,else x1
x and yif x is false,then x,else y2
not xif x is false,then true,else false3

1. or是一个短路操作符,如果x符合条件则不再判断y
2. and也是一个短路操作符,如果x不符合条件,则不再判断y
3. not在布尔运算符中优先级最高,但布尔运算符对比其他运算符优先级较低。所以,not a==b被解释为not (a==b),而a == not b 是一种语法错误。

比较运算符

Python中共有8种比较运算符,且都处在同一优先级。比较运算符可以做链式比较,例如:x < y <= z 等同于x

数字运算符

数字类型主要有三种:整型,浮点数和复数类型。布尔值是整数类型的一个子类型。整型为无限精度,浮点型类似C语言中的双精度。而精度一般是有所用机器的系统决定的,可通过sys.float_info来查看浮点的精度范围。复数类型有一个实数部分和一个虚数部分,两部分都为浮点类型,假设变量z为一个复数,可以通过z.realz.imag来得到实数和虚数部分。标准库还包括其他的数字类型,fractions保存有理数,decimal保存用户自定义精度的浮点数。

Python支持不同数字类型的混合运算:当一个二进制操作符运算不同数字类型的运算数时,“窄”类型的操作数会被转换成另一种类型后进行运算,宽窄等级如下:整型<浮点型<复数类型。两个不同类型的数字对比也遵循如上规则。int()、float()、complex()等构造器可以用来构建对应的数字类型。

除了复数之外的所有数字类型都支持如下操作符,这些操作符是以优先级从小到大排列的。所有数字运算符都要比比较运算符优先级高。

操作符结果对应说明
x + yx和y之和
x - yx减y之差
x * yx乘以y
x / yx除以y
x // yx除以y取模说明1
x % yx除以y取余数说明2
-xx取反
+xx不变
abs(x)x绝对值
int(x)将x转换为整数类型说明3、说明6
float(x)将x转换为浮点类型说明4、说明6
complex(re, im)转换为复数类型,其中re为实数部分,im为虚数部分,im默认为0说明6
c.conjugate()数字c的复数类型
divmod(x, y)(x // y, x % y)组成的元组说明2
pow(x, y)x的y次方幂说明5
x ** yx的y次方幂说明5

说明:

  1. 与除法相关,结果会倾向于较小的那个整数:1 // 2 返回0,(-1) // 2 返回-1,1 // (-2) 返回-1,(-1) // (-2) 返回0。
  2. 这种运算不适用于复数。
  3. 将浮点型转换为整型的小数部分取舍类似于C语言;可以参考math模块中的floor()和ceil()函数。
  4. float可以接受字符串参数如“nan”和“inf“以及一个设置前缀的位置参数”+“或”-“来表示NaN的正负极限。
  5. Python定义了pow(0, 0)以及0 ** 0的值为1.
  6. 接收0-9数字以及任何Unicode对等量。

所有实数类型可以进行如下操作:

操作结果
math.trunc(x)结果截断至整数
round(x[, n])保存到小数点后n位数,n默认为0
math.floor(x)结果取到整数,会取最小整数,例如:1.111和1.999结果都为1
math.ceil(x)结果取到整数,会取最大整数,例如:1.111和1.999结果都为2
比特运算

整数支持一种只对比特串有效的操作。整数转换为二进制,负数被转换为自身的补码。

这种二进制的按位操作的优先级低于数字运算,但高于对比运算。一元操作符~的优先级同其他一元数字运算一致(例如+和-)。

以下是比特运算符,以优先级从低到高排序:

操作结果举例
x | yx和y按位或操作4|2=6,100|010 中,只要一位上有一个值为1,则结果中此位值为1,所以本例结果为110,十进制6
x ^ yx和y按位异或操作4^2,100^010,对应位相加,返回结果为110,二进制为
x & yx和y按位与操作4&2,100&010,只有某位的值都为1时,此位值才是1,其余情况都为0,因此本例结果为000,二进制0
x << yx按位左移n位4<<2=16, 100左移两位为10000,结果为16
x >> yx按位右移n位4>>2=1, 100左移两位为1, 结果为1
~xx按位反转~4=-5,-(100+1) =-5,此运算符为一元运算符,运算规则为~x=-(x+1)

说明:

  1. 按位左移和右移的位数不能为负数,否则会引发ValueError异常;
  2. 按位左移运算等价于乘以pow(2, n),且不做溢出检测;
  3. 按位右移运算等价于除以pow(2, n),且不做溢出检测。
整型的其他方法
  • int.bit_length()

    返回一个整数的二进制位数。

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

    相当于:

    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
  • 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() // 8) + 1, byteorder='little')
    b'\xe8\x03'
  • 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
浮点型的其他方法
  • float.as_integer_ratio()

    返回一个由两个整数组成的元组,元组的第一个元素除以第二个元素的值为该浮点数。

    >>> a=1.234
    >>> a.as_integer_ratio()
    (694680242521899, 562949953421312)
    >>> 694680242521899/562949953421312
    1.234

    如果是无限循环小数,则抛出OverflowError异常。而对于NaN则会抛出ValueError异常。

  • float.is_integer()

    >>> (-2.0).is_integer()
    True
    >>> (3.2).is_integer()
    False
  • float.hex()

    返回表示该浮点数的十六进制字符串。对于有限浮点数,这种表示方法总是以0x开头,并以p结尾。

  • float.fromhex(s)

    类方法,返回十六进制字符所表示的浮点数。

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

数字对比其实就是对比两者的哈希值,哈希值一致,则两个数相等。

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_ = 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_ = (abs(m) % P) * pow(n, P - 2, P) % P
    if m < 0:
        hash_ = -hash_
    if hash_ == -1:
        hash_ = -2
    return hash_

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_ = 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_ = (hash_ & (M - 1)) - (hash & M)
    if hash_ == -1:
        hash_ == -2
    return hash_
序列类型—str,bytes,bytearray,list,tuple,range

序列通常有如下通用操作:

操作结果说明
x in s当x属于s时返回True,否则返回False1
x not in s当x不属于s时返回True,否则返回False1
s + t返回序列x和t按顺序拼接的结果6
s*n, n*s将s做n次浅拷贝并拼接后返回2
s[i]返回索引为i的元素,索引从0开始3
s[i:j]返回索引从i到j-1的切片3,4
s[i:j:k]返回索引从i到j,步长为k的切片3,5
len(s)返回序列的长度
min(s)返回序列最小元素
max(s)返回序列最大元素
s.index(i)返回序列中首个元素为i的索引值
s.count(i)返回序列中i元素出现的次数

序列类型支持对比,两个序列相同的条件是,长度相同、每个元素相同、序列类型相同。

说明:

  1. 当序列为字符串时,in和not in操作类似检测是否为子字符串;

  2. 当n的值小于0时,将一律当做0处理,这种情况下会返回空序列。需要注意的是此时为浅拷贝:

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

    如果想要得到不同的结果,可以参考下列操作:

    >>> lists = [[] for i in range(3)]
    >>> lists[0].append(3)
    >>> lists[1].append(5)
    >>> lists[2].append(7)
    >>> lists
    [[3], [5], [7]]
  3. 如果i或j是复数,则索引是从后往前算:len(s) + i 或len(s) + j来替换该负值。但-0依然是0。

  4. 如果i或者j比len(s)大,则会替换为len(s)。如果i缺失或者为None,则会替换为0;如果j缺失或者为None,则会替换为len(s)。如果i大于等于j,则切片为空。

  5. 从i到j,步长为k的切片,其元素索引为i,i+k,i+2*k,…直到达到或超过j的值,但永不包含j。如果i或j大于len(s),则替换为len(s);如果i缺失或为None,则替换为0;如果j缺失或为None,则替换为len(s)。如果k缺失,取默认值1。

  6. CPython解释器细节:如果s和t都为字符串,有些Python解释器例如CPython可以写成这种格式:s = s + t或s += t。为了增强解释器兼容性,这种情况最好使用字符串内置方法str.join([s, t])

字符串格式化操作

这里的字符串格式化方式可能在未来弃用,请关注版本更新信息

字符串对象有一个特殊的内置操作符:%,用来做字符串格式化。

当格式化一个值的时候,将被格式化的内容放到操作符%后:

>>> a = "Nemo"
>>> b = "hello %s" % a
>>> b
'hello Nemo'

当格式化多个值时,各个值按照位置关系,通过元组传入到字符串中:

>>> a = "hello"
>>> b = "Nemo"
>>> c = "%s %s" % (a, b)
>>> c
'hello Nemo'

当格式化内容存在字典时:

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

其中%后跟着的字母为占位符,不同占位符所支持格式化的类型不同:

占位符说明
‘d’整数
‘i’整数
‘o’八进制数
‘u’废弃类型,和’d’差不多
‘x’十六进制(小写)
‘X’十六进制(大写)
‘e’浮点数指数格式(小写)
‘E’浮点数指数格式(大写)
‘f’浮点数十进制格式(小写)
‘F’浮点数十进制格式(大写)
‘g’浮点数格式。当指数级别小于-4或更低精度时使用指数格式(小写),否则使用十进制格式
‘G’浮点数格式。当指数级别小于-4或更低精度时使用指数格式(大写),否则使用十进制格式
‘c’单个字母(可以是整数或单个字母)
‘r’字符(使用repr()方法来转换任意Python对象)
’s’字符(使用str()方法来转换任意Python对象)
‘a’字符(使用ascii()方法来转换任意Python对象)
‘%’如果没有传入任何参数,则结果中显示原字符’%’
range类型

range类型是属于不可变序列,通常用于循环操作。使用range的好处是,不论range长度多少,它都占用等量的内存。

range对象支持索引操作、容器操作、迭代操作、len()函数,以及:

  • range.count(x)

    返回range对象中x元素存在的个数。

  • range.index(x)

    返回range对象中s[i] == x 的索引值i。如果x不在range对象中,则抛出ValueError异常。

可变序列

列表和bytearray属于可变序列,字符串和元组属于不可变序列。可变序列支持对序列中的元素更改,不可变序列中的元素一旦创建不可更改。可变序列有如下操作,需要注意的是列表元素可以为任意元素,bytearray的元素只能是范围0~256的整数:

操作结果
s[i] = x将索引i的元素的值替换为x
s[i:j] = t将索引为i到j的切片替换为可迭代对象t
del s[i:j]类似s[i:j] = []
s[i:j:k] = t将s[i:j:k]的元素替换为t
del s[i:j:k]将s[i:j:k]里的元素删除
s.append(x)等同于s[len(s) : len(s)] = [x]
s.extend(x)等同于s[len(s) : len(s)] = x
s.count(x)返回s中值为x元素的个数
s.index(x[, i[, j]])返回序列i到j切片中元素值等于x的最小索引
s.insert(i, x)等同于s[i:i] = [x]
s.pop([i])等同于 x = s[i]; del s[i]; return x
s.remove(x)等同于del s[s.index(x)]
s.reverse()反转序列元素
s.sort([key[, reverse]])对序列元素排序

说明:

  • 可迭代对象t的长度应当与被替换的切片长度一致;

  • x可以为任意可迭代对象;

  • 当序列s中不包含值为x的元素时,index方法会抛出ValueError异常;
  • 当insert方法传入负索引时,序列长度会增加。
  • pop方法的参数i默认值为-1,即默认删除序列最后一个元素;
  • 当排序或反转一个大序列时,sort方法和reverse方法开销较小,但不好的一点是这两种方法都不返回操作过的序列;
  • sort方法必须传入排序关键字参数,作为排序的对比依据。key参数接收一个函数,对序列里每个值处理后进行排序,例如:key=str.lower,这样会把序列中的元素。
bytes和bytearray

bytes和bytearray对象,都属于字节字符串,可以使用字符串的所有方法,但bytes不接收str做参数,同理str也不接收bytes做参数。

a = "abc"
b = a.replace("a", "f")
a = b"abc"
b = a.replace(b"a", b"f")
  • bytes.decode(encoding=”utf-8”, errors=”strict”) bytesarray.decode(encoding=”utf-8”, errors=”strict”)

    返回字节解码后的字符串,默认编码方式为utf-8。errors参数为处理异常的模式,默认为strict,即编码的时候遇到错误会抛出UnicodeError异常。其他可用值有’ignore’,’replace’等。

  • bytes.fromhex(sting) bytesarray.fromhex(string)

    类方法,返回对string解码后的字符对象。参数string中,每个字节必须至少包含两个十六进制数,空格会被忽略。

    >>> bytes.fromhex('f0 f1f2  ')
    b'\xf0\xf1\xf2'
  • bytes.translate(table[, delete]) bytearray.translate(table[, delete])

    返回bytes或bytearray对象的副本,其中删除了可选参数delete中出现的左右字节,其余字节通过给定转换表映射,该转换表必须是长度为256的字节对象。

    可以通过bytes.maketrans()方法来构造一个转换表。

    如果只是想删除字符,可以将table参数设为None。

    >>> b'read this short text'.translate(None, b'aeiou')
    b'rd ths shrt txt'
  • bytes.maketrans(from, to) bytearray.maketrans(from, to )

    静态方法,返回一个转换表,这个表通常提供给bytes.translate()使用。会把from和to中相同位置的字符做映射,而from和to必须为字节类型并且长度相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值