点击上方“蓝字”关注我们,第一时间推送优质文章!
前言
大家好,我是潜心。关注人数终于突破了100,非常感谢大家的关注。这是改名后也是「通过Docs学Python」系列正文的第一篇文章。之前本来想写专业方向的内容,奈何一没影响力,二没实力,实在没人看,所以先放一放,不过不定期更新自己读过的论文。语法问题还是不讲了吧,这里默认大家都是具有一定基础的同学。本期讲述Python中的内置类型,应该会分2-3节,内置函数用到的话会附在最后。
本文约3.3k字,预计阅读25分钟。
Python内置类型
内置类型,即Python中的基本数据类型(简单认为,你就可以联系C、C++、Java等你学过的语言,它们需要定义数据类型,如int、float、double、string等,但Python不用在前面注明这是什么类型的变量或常量)。主要内置类型有「数字(numerics)」、「序列(sequences)」、「映射(mappings)」、「类(classes)」、「实例(instances)」和「异常(exceptions)」。
数字类型
数字是由数字字面值或内置函数与运算符的结果来创建的。存在三种不同的数字类型: 整数, 浮点数 和复数。此外,「布尔值」属于整数的子类型,True
为1,False
为0。
不带修饰的整数字面值(包括十六进制、八进制和二进制数)会生成整数,整数「具有无限的精度」(与Java不同);
包含小数点或幂运算符的数字字面值会生成浮点数, 浮点数通常使用 C 中的
double
来实现,不区分float
与double
;复数包含实部和虚部,分别以一个浮点数表示。在数字字面值末尾加上
'j'
或'J'
会生成虚数(实部为零的复数),你可以将其与整数或浮点数相加来得到具有实部和虚部的复数,要从一个复数 z 中提取这两个部分,可使用z.real
和z.imag
。(很少用,潜心从来没用过)
>>> i, f, c = 1, 1.0, 1 + 1j
>>> type(i), type(f), type(c)
(<class 'int'>, <class 'float'>, <class 'complex'>)
>>> type(int(f)), type(float(i))
(<class 'int'>, <class 'float'>)
>>> c.real, c.imag
(1.0, 1.0)
其中,type()
①,int()
②,float()
③,为「内置函数」。
整数类型的按位运算
按位运算只对整数有意义。(这里需要同学对二进制有一定的了解,因为计算机中所有的内容都是用0、1的二进制所表示的)
二进制按位运算的优先级全都低于数字运算,但又高于比较运算;
运算 | 结果 |
---|---|
x | y | x 和 y 按位 或,只要有一个位上x/y有1,即为1 |
x ^ y | x 和 y 按位 异或,即x与y对应位不相同为1 |
x & y | x 和 y 按位 与,即x与y对应位都为1,结果才为1 |
x << n | x 左移 n 位,等于乘以pow(2, n) |
x >> n | x 右移 n 位,等于除以pow(2, n) |
~x | x 逐位取反 |
>>> 1 | 2 # 00000001 | 00000010 = 00000011 = 3
3
>>> 1 ^ 2 # 00000001 ^ 00000010 = 00000011 = 3
3
>>> 1 & 2 # 00000001 & 00000010 = 00000000 = 0
0
>>> 2 << 1 # 00000010 >> 1 = 00000100 => 4
4
>>> 2 >> 1 # 00000010 << 1 = 00000001 => 1
1
>>> ~ 1 # ~ 00000001 = 11111110 => -2
-2
关于 「取反操作」 :这里我们假定为8位,计算机普遍使用 「补码表示负数」 。知道一个数的补码,要求其值的方法是:首先看符号位也就是最左的一位,如果是1代表是负数如果是0代码是正数,然后对该值取反,再+1,得到其源码。故上述得到11111110
,为某个数的补码,欲得到源码:取反,再加1,最后再加个负号,即-00000010=>-2
序列类型
有三种基本序列类型:「list」,「 tuple」 和「range」对象。序列又分为可变序列(list)和不可变序列(tuple、range)。两者的区别是:可变序列支持原位改变。即能实现例如:l[i]=4
这个操作。首先介绍通用序列的操作,再介绍可变序列和不可变序列。
通用序列操作
大多数序列类型,包括可变类型和不可变类型都支持下表中的操作。其中s和t是具有相同类型的序列,n, i, j和 k是整数,x是任何满足s所规定的类型和值限制的任意对象。
运算 | 结果 |
---|---|
x in s | 如果 s 中的某项等于 x 则结果为 True ,否则为 False |
x not in s | 如果 s 中的某项等于 x 则结果为 False ,否则为 True |
s + t | s 与 t 相拼接 |
s * n 或 n * s | 相当于 s 与自身进行 n 次拼接 |
s[i] | s 的第 i 项,起始为 0; 若i为负数,则变为第 len(s)+i 项,即表示倒数第i个 |
s[i:j] | s 从 i 到 j 的切片 |
s[i:j:k] | s 从 i 到 j 步长为 k 的切片,[i, i+k, i+2*k,...] |
len(s) | s 的长度 |
min(s) | s 的最小项 |
max(s) | s 的最大项 |
s.index(x) | x 在 s 中首次出现项的索引号 |
s.count(x) | x 在 s 中出现的总次数 |
>>> l = [1, 2, 3, 4]
>>> 2 in l
True
>>> 3 not in l
False
>>> l1 = [5, 6, 7]
>>> l = l + l1
>>> l
[1, 2, 3, 4, 5, 6, 7]
>>> l[0], l[-1], l[0:7], l[0:7:2]
(1, 7, [1, 2, 3, 4, 5, 6, 7], [1, 3, 5, 7])
>>> len(l)
7
>>> min(l), max(l)
(1, 7)
>>> l.index(5), l.count(2)
(4, 1)
关于第4条运算,n 次拼接操作, 序列 s 中的项并不会被拷贝,它们会被多次引用:
>>> l = [1, 2, 3] * 2
>>> l
[1, 2, 3, 1, 2, 3]
>>> l = [[]] * 3
>>> l
[[], [], []]
>>> l[0].append(2)
>>> l
[[2], [2], [2]]
出现上述情况的具体的原因在于 [[]]
是一个包含了一个空列表的单元素列表,所以 [[]] * 3
结果中的三个元素都是对这一个空列表的引用。修改 l
中的任何一个元素实际上都是对这一个空列表的修改。
若是想要创建一个二维列表(很多地方都会用到):
>>> l = [[] for _ in range(3)]
>>> l
[[], [], []]
>>> l[0].append(2)
>>> l
[[2], [], []]
可变序列类型
以下表格中的操作是在可变序列类型上定义的。
表格中的 s 是可变序列类型的实例,t 是任意可迭代对象,而 x 是符合对 s 所规定类型与值限制的任何对象。
运算 | 结果 |
---|---|
s[i] = x | 将 s 的第 i 项替换为 x |
s[i:j] = t | 将 s 从 i 到 j 的切片替换为可迭代对象 t 的内容, 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) | 将 x 添加到序列的末尾 (等同于 s[len(s):len(s)] = [x] ) |
s.clear() | 从 s 中移除所有项 (等同于 del s[:] ) |
s.copy() | 创建 s 的浅拷贝 (等同于 s[:] ) |
s.extend(t) 或 s += t | 用 t 的内容扩展 s (基本上等同于 s[len(s):len(s)] = t ) |
s *= n | 使用 s 的内容重复 n 次来对其进行更新 |
s.insert(i, x) | 在由 i 给出的索引位置将 x 插入 s (等同于 s[i:i] = [x] ) |
s.pop([i]) | 提取在 i 位置上的项,并将其从 s 中移除 |
s.remove(x) | 删除 s 中第一个 s[i] 等于 x 的项目。 |
s.reverse() | 就地将列表中的元素逆序。 |
>>> l = [1, 2, 3]
>>> l[2] = 4
>>> l
[1, 2, 4]
>>> l[0:2] = [6, 5]
>>> l
[6, 5, 4]
>>> del l[0:1]
>>> l
[5, 4]
>>> l.append(3)
>>> l
[5, 4, 3]
>>> l2 = l.copy()
>>> l.clear()
>>> l2, l
([5, 4, 3], [])
>>> l2 = l.copy()
>>> l.clear()
>>> l2, l
([5, 4, 3], [])
>>> l2.extend([2, 1])
>>> l2
[5, 4, 3, 2, 1]
>>> l2.reverse()
>>> l2
[1, 2, 3, 4, 5]
>>> l2.pop(-1)
5
>>> l2
[1, 2, 3, 4]
不可变序列类型
不可变序列类型普遍实现可变序列类型的错做,未实现的唯一操作就是对 hash()
内置函数的支持,尝试对包含有不可哈希值的不可变序列进行哈希运算将会导致 TypeError
。
这种支持允许不可变类型,例如 tuple
实例被用作 dict
键(list为可变序列类型就无法用做dict
键)。
>>> d = {(1):'1', (2):'2', (3):'3'}
>>> d = {[1]:'1', [2]:'2', [3]:'3'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
1. 列表
列表是可变序列,通常用于存放同类项目的集合。
class list([iterable])
,iterable表示一个可迭代对象。可以用多种方式构建列表:
使用一对方括号来表示空列表:
[]
使用方括号,其中的项以逗号分隔:
[a]
,[a, b, c]
使用列表推导式:
[x for x in iterable]
使用类型的构造器:
list()
或list(iterable)
注意:使用构造器时,如果iterable已经是一个列表,将创建并返回其副本,类似于 iterable[:]
。
>>> list('abc')
['a', 'b', 'c']
>>> list((1, 2, 3))
[1, 2, 3]
对于字符串,上述其实是一个很好用的「小技巧」,将字符串中的字符转化为列表中的值。
列表实现所有通用和可变序列的操作,还提供以下方法:
sort(*, key=None, reverse=False)
,此方法会对列表进行原地排序:
key 指定带有一个参数的函数,用于从每个列表元素中提取比较键 (例如
key=str.lower
)。对应于列表中每一项的键会被计算一次,然后在整个排序过程中使用。默认值None
表示直接对列表项排序而不计算一个单独的键值。reverse 为一个布尔值。如果设为
True
,则每个列表元素将按反向顺序比较进行排序。
>>> l = [3, 2, 4, 1, 6]
>>> l.sort()
>>> l
[1, 2, 3, 4, 6]
>>> l.sort(reverse=True)
>>> l
[6, 4, 3, 2, 1]
>>> l = ['bca', 'bba', 'baa']
>>> l.sort(key=lambda x:x[1])
>>> l
['baa', 'bba', 'bca']
2.元组
元组是不可变序列,通常用于储存异构数据的多项集(例如由 enumerate()
④内置函数所产生的二元组)。元组也被用于需要同构数据的不可变序列的情况(例如允许存储到 set
或 dict
的实例)。
class tuple([iterable])
,可以用多种方式构建元组:
使用一对圆括号来表示空元组:
()
使用一个后缀的逗号来表示单元组:
a,
或(a,)
使用以逗号分隔的多个项:
a, b, c
or(a, b, c)
使用内置的 tuple():
tuple()
或tuple(iterable)
3. range对象
range
类型表示不可变的数字序列,通常用于在 for
循环中循环指定的次数。
class range(stop)
,
class range(start, stop[, step])
range 构造器的参数必须为整数。如果省略 step 参数,其默认值为 1
。如果省略 start 参数,其默认值为 0
。
如果 step 为正值,确定 range 内容的公式为 r[i] = start + step*i
其中 i >= 0
且 r[i] < stop
。
如果 step 为负值,确定 range 内容的公式仍然为 r[i] = start + step*i
,但限制条件改为 i >= 0
且 r[i] > stop
.
range 对象确实支持负索引,但是会将其解读为从正索引所确定的序列的末尾开始索引。
>>> for i in range(5):
... print(i)
0
1
2
3
4
>>> for i in range(5, -1, -1):
... print(i)
5
4
3
2
1
0
总结
本期主要讲述了Python内置类型中的「数字类型」与「序列类型」。数字分为:整数、浮点数、复数;序列类型有:list、tuple、range对象。下期潜心会介绍文本序列类型、集合类型、映射类型等。喜欢的小伙伴可以点个关注嘛!也希望能够给你们的同学推荐下好嘛!
内置函数
①type()
class type(object)
,传入一个参数时,返回 object 的类型, 返回值是一个 type 对象。
②int()
class int([x])
class int(x, base=10)
返回一个基于数字或字符串 x 构造的整数对象,或者在未给出参数时返回 0
。
如果 x 不是数字,或者有 base 参数,x 必须是字符串、bytes。默认的 base 为 10 ,允许的进制有 0、2-36。即将base进制的x转为10进制。
>>> int('010', 2)
2
③float()
class float([x])
返回从数字或字符串 x 生成的浮点数。如果实参是字符串,则它必须是包含十进制数字的字符串,字符串前面可以有符号,之前也可以有空格。可选的符号有 '+'
和 '-'
; '+'
对创建的值没有影响。实参也可以是 NaN(非数字)、正负无穷大的字符串。
>>> float('inf') # inf:INFINITY,无穷大的含义
inf
>>> float('1e6')
1000000.0
④enumerate()
enumerate(iterable, start=0)
,返回一个枚举对象。iterable 必须是一个序列,或 iterator,或其他支持迭代的对象。 enumerate()
返回包含一个计数值(从 start 开始,默认为 0)和通过迭代 iterable 获得的值。**通常在for循环中需要索引时用到。
for index, n in enumerate(range(5)):
...
参考文献
[1] Python官方文档.
往期精彩回顾
爬虫基础知识(一)多线程与threading模块
哔哩哔哩爬虫实战----验证码识别
扫码关注更多精彩