说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
序列(Sequence)是有顺序的数据列,Python 有三种基本序列类型:list, tuple 和 range 对象,序列(Sequence)是有顺序的数据列,二进制数据(bytes) 和 文本字符串(str)也是序列类型,它们是特殊序列类型,会有一些特殊的性质和操作。
Python 的内置序列类型有:
类型 | 创建方法 | 可变性 | 特别方法 |
---|---|---|---|
列表 | list() | 可变 | sort() |
元组 | tuple() | 不可变 | |
等差数列 | range() | 不可变 | 属性方法 |
字符串 | str() | 不可变 | 字符的方法 |
字节串 | bytes() | 不可变 | |
字节数组 | bytearray() | 可变 | |
内存视图 | memoryview() | 不可变 |
要注意的是,集合、字典不是序列类型,虽然字典在最新的 Python 版本中具备了元素顺序特性,但这不是一种「保证」。
如何判断一个数据是不是序列类型呢?
from collections import abc
a = [1, 2, 3]
b = {1, 2, 3}
c = (1, 2, 3)
isinstance(a, abc.Sequence)
# True
isinstance(b, abc.Sequence)
# False
# 可变类型
isinstance(a, abc.MutableSequence)
# True
isinstance(c, abc.MutableSequence)
# False
序列的特点是由若干元素组成,元素的分布有顺序,因此根据这个特点,它们支持一些共性的操作。
以下是所有序列类型均支持的操作:
运算 | 结果: | 备注 |
---|---|---|
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 | 切片操作 |
s[i:j] |
s 从 i 到 j 的切片 | |
s[i:j:k] |
s 从 i 到 j 步长为 k 的切片 | |
len(s) |
s 的长度 | |
min(s) |
s 的最小项 | |
max(s) |
s 的最大项 | |
s.index(x[, i[, j]]) |
x 在 s 中首次出现项的索引号 (索引号在 i 或其后且在 j 之前) |
count 方法 |
s.count(x) |
x 在 s 中出现的总次数 | index 方法 |
for i in x:pass |
迭代 | |
hash(x) |
对象的哈希值 | 仅不可变序列 |
sorted(x) |
排序 | |
all(x) 或者 any(x) |
全真或者有真检测 | |
iter(x) |
生成迭代器 |
注:以上部分操作需要额外的特殊方法实现。当我们在处理数据量大且需频繁查找元素(如 in 操作)时,最好使用 set、dict ,这样将会大幅度提升处理速度。
以下是仅可变序列支持的操作:
运算 | 结果: | 备注 |
---|---|---|
s[i] = x |
将 s 的第 i 项替换为 x | |
s[i:j] = t |
将 s 从 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) |
将 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() 或 s.pop(i) |
提取在 i 位置上的项,并将其从 s 中移除 | |
s.remove(x) |
删除 s 中第一个 s[i] 等于 x 的项目。 |
|
s.reverse() |
就地将列表中的元素逆序。 |
序列是一种可迭代(iterable)的对象,它支持通过 __getitem__()
特殊方法来使用整数索引进行高效的元素访问,并定义了一个返回序列长度的 __len__()
方法。内置的序列类型有 list、str、tuple 和 bytes。注意虽然 dict 也支持 __getitem__()
和 __len__()
,但它被认为属于映射而非序列,因为它查找时使用任意的不可变的(immutable)键而非整数。
collections.abc.Sequence
抽象基类定义了一个更丰富的接口,它在 __getitem__()
和 __len__()
之外又添加了 count()、index()、__contains__()
和 __reversed__()
。 实现此扩展接口的类型可以使用 register() 来显式地注册。
我们定义一个包的类,包有名字和存放的一系列物品。根据序列原理,我们将其实现为一个序列,支持序列的一些操作来读取包里物品。
class Bag():
def __init__(self, name, contents) -> None:
self.name = name
self.contents = contents
def __repr__(self) -> str:
return f'<Bag: {self.name}>'
def __len__(self):
return len(self.contents)
def __getitem__(self, idx):
return self.contents[idx]
我们来实例化并进行操作,实例化一个钱包,里边存放不同面额的人民币:
# 实例化为一个钱包
w = Bag('wallet', [1, 5, 10, 20, 100])
w
# <Bag: wallet>
进行一些序列的操作:
max(w) # 100
len(w) # 5
w[-1] # 100
10 in w # True
for i in w: print(i)
'''
1
5
10
20
100
'''
hash(w) # 8766419859204
all(w) # True
sorted(w) # [1, 5, 10, 20, 100]
[*reversed(w)] # [100, 20, 10, 5, 1]
iter(w) # <iterator at 0x7f91757771f0>
更新时间:2024-01-15 15:58:01 标签:python 序列 数据类型