Python数据类型-基础数据类型-序列类型 --- list 列表, tuple 元组, range
2025-8-30
| 2025-8-31
Words 5531Read Time 14 min
type
status
date
slug
summary
tags
category
icon
password

📝 通用序列操作

大多数序列类型,包括可变类型和不可变类型都支持下表中的操作。collections.abc.Sequence ABC被提供用来更容易地在自定义序列类型上正确地实现这些操作。
此表按优先级升序列出了序列操作。在表格中,s 和 t 是具有相同类型的序列,n, i, j 和 k 是整数而 x 是任何满足 s 所规定的类型和值限制的任意对象。
in 和 not in 操作具有与比较操作相同的优先级。+ (拼接) 和 * (重复) 操作具有与对应数值运算相同的优先级。
运算
结果
备注
x in s
若 s 中某一项等于 x 则为 True,否则为 False
(1)
x not in s
若 s 中某一项等于 x 则为 False,否则为 True
(1)
s + t
将序列 s 与 t 拼接得到新序列
(6)(7)
s * nn * s
将序列 s 重复 n 次后拼接成新序列
(2)(7)
s\[i]
返回序列 s 的第 i 项,下标从 0 开始
(3)
s\[i:j]
返回序列 s 从索引 i 到 j(不含 j)的切片
(3)(4)
s\[i:j:k]
返回序列 s 从索引 i 到 j、步长为 k 的切片
(3)(5)
len(s)
返回序列 s 的元素个数
min(s)
返回序列 s 中的最小项
max(s)
返回序列 s 中的最大项
s.index(x\[, i[, j]])
返回 x 在 s 中首次出现的位置索引;可限定搜索范围 [i, j)
(8)
s.count(x)
返回 x 在序列 s 中出现的总次数

1、index(self, value, start=0, stop=sys.maxsize) → int

1.1、在序列的指定切片 [start:stop) 范围内,从左到右查找第一次出现的元素 value,并返回其下标。若未找到,抛出 ValueError。

1.2、参数

  • value(必选):要查找的元素,与序列元素做 == 比较。
  • start(可选,默认为 0):切片起始下标(包含)。
  • stop(可选,默认为 sys.maxsize):切片结束下标(不包含)。

1.3、返回值

  • 找到时返回 int 类型的下标(相对于原序列,而非切片)。
  • 未找到时抛出 ValueError: <value> is not in sequence。

1.4、边界/细节

  • 支持负索引;start 或 stop 越界会被自动截断。
  • 若序列中允许重复元素,只返回 最左侧 的第一次出现。
  • 时间复杂度平均为 O(n),因为需要线性扫描。

2、count(self, value) → int

2.1、统计序列中 所有位置(无切片参数)与 value 相等的元素出现次数。

2.2、参数

  • value(必选):要计数的元素,使用 == 比较。

2.3、返回值

  • int:出现次数;若一次也没有返回 0。
  • 不会抛出异常,即使元素不存在。

2.4、边界/细节

  • 同样使用线性扫描,时间复杂度 O(n)。
  • 对于可变序列(如 list),统计的是调用时刻的快照。
  • 字符串、元组、列表、bytes 等内部实现均遵循同一语义。

3、len()获取列表长度

4、max()获取列表值最大的元素

5、min()获取列表值最小的元素

📝 不可变序列类型

不可变序列类型普遍实现而可变序列类型未实现的唯一操作就是对hash() 内置函数的支持。
这种支持允许不可变类型,例如tuple 实例被用作dict 键,以及存储在set 和frozenset 实例中。
尝试对包含有不可哈希值的不可变序列进行哈希运算将会导致TypeError。

📝 可变序列类型

以下表格中的操作是在可变序列类型上定义的。collections.abc.MutableSequence ABC 被提供用来更容易地在自定义序列类型上正确实现这些操作。
表格中的 s 是可变序列类型的实例,t 是任意可迭代对象,而 x 是符合对 s 所规定类型与值限制的任何对象 (例如,bytearray 仅接受满足 0 <= x <= 255 值限制的整数)。
运算
结果
备注
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 的元素
(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
用 t 的内容扩展 s
等同于 s\[len(s):len(s)] = t
s *= n
使用 s 的内容重复 n 次来对其进行更新
(6)
s.insert(i, x)
在索引 i 处插入 x
等同于 s\[i:i] = \[x]
s.pop() 或 s.pop(i)
移除并返回索引 i 处的元素
(2)
s.remove(x)
移除第一个等于 x 的元素
(3)
s.reverse()
就地逆序列表元素
(4)

1、append(self, value) → None

  • 作用:在序列尾部追加单个元素。
  • 参数:value – 待追加的对象。
  • 返回值:None(就地修改)。
  • 复杂度:均摊 O(1)。

2、clear(self) → None

  • 作用:删除序列中所有元素,使其长度变为 0。
  • 参数:无。
  • 返回值:None。

3、copy(self) → MutableSequence

  • 作用:返回序列的浅拷贝(新对象,元素本身不复制)。
  • 参数:无。
  • 返回值:与原序列同类型的空壳副本。

4、extend(self, iterable) → None

  • 作用:将可迭代对象中的所有元素依次追加到尾部。
  • 参数:iterable – 任意可迭代对象(列表、元组、生成器等)。
  • 返回值:None。
  • 复杂度:O(k),k 为 iterable 长度。

5、insert(self, index, value) → None

  • 作用:在指定下标前插入元素;负索引也可。
  • 参数:index – 插入位置;value – 待插入元素。
  • 返回值:None。
  • 复杂度:O(n)。

6、pop(self, index=-1) → element

  • 作用:移除并返回指定下标的元素;默认移除最后一个。
  • 参数:index – 可选,默认为 -1。
  • 返回值:被弹出的元素。
  • 异常:IndexError(空序列或越界)。

7、remove(self, value) → None

  • 作用:删除第一个与 value 相等的元素。
  • 参数:value – 待移除的值(按 == 比较)。
  • 返回值:None。
  • 异常:ValueError(元素不存在)。

8、reverse(self) → None

  • 作用:就地反转序列顺序。
  • 参数:无。
  • 返回值:None。
  • 复杂度:O(n)。

📝 列表 list

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

1、构造方法:

1.1、字面量构造(空列表或初值列表)

最轻量,O(1) 创建;
只负责“容器”,不提供线程安全或性能优化

1.2、构造函数 list(iterable)

任何可迭代对象 → 列表;
复杂度 O(n),n 为去重后元素个数。

1.3、列表推导式 / 生成器表达式

语法灵活,可直接生成“队列初始数据”。

1.4、从其他容器转换

源容器
示例
备注
tuple
list((1,2,3))
元组 → 列表
set
list({1,2,3})
集合 → 列表(无序)
dict
list({'a':1,'b':2})
键视图 → 列表
文件对象
list(open('file.txt'))
每行一个元素

1.5、 展开构造

Python 3.5+ 的解包语法,用于“一次性拼接”。

1.6、双端队列(deque)—— 官方推荐高性能队列

生产环境 推荐 collections.deque,因为它在两端插入/删除都是 O(1),而 list.insert(0, x) 是 O(n)。
完全兼容 list 的迭代、切片读取;
额外方法:appendleft, popleft, extendleft, rotate, maxlen。

1.7、线程安全队列(queue 模块)

若需要在 多线程 中当真正队列,使用 queue.Queue/LifoQueue/PriorityQueue,内部用锁保护
与 list 接口不同:通过 put, get, task_done 管理。

1.8、性能对比速览

操作
list
deque
Queue
尾部 append
O(1)
O(1)
O(1)
头部 insert
O(n)
O(1)
O(1)
线程安全
可切片
临时/单线程:q = \[]q = list(iterable)
高频两端操作:用 collections.deque(iterable)
多线程安全:用 queue.Queue(maxsize)

2、list.sort(*, key=None, reverse=False)

2.1、作用

  • 原地重排:调用后原列表顺序被永久改变。
  • 稳定排序:排序前后,相等元素的相对顺序不变。
  • 多字段排序:可一次指定多个键,实现多级排序(例如先按年龄再按姓名)。

2.2、参数

形参
类型
默认值
说明
key
callable 或 None
None
排序键函数。对每个元素调用 key(element),返回值作为排序依据。常见用法:<br>- key=str.lower(忽略大小写)<br>- key=lambda x: x.age(按对象属性)<br>- key=operator.itemgetter(1)(按元组第二字段)
reverse
bool
False
True降序排序;False 为升序。

2.3、返回值

始终返回 None。
因为排序是原地操作,所以 不返回新列表;若写 new_list = old_list.sort(),会得到 None,这是常见错误。

3、公共功能

3.1、运算符 +

相加,两个列表相加获取生成一个新的列表。

3.2、运算符 *

相乘,列表*整型 将列表中的元素再创建N份并生成一个新的列表。

3.3、索引(下标)取值

💡
超出索引范围会报错。
由于字符串是不可变类型,所以他只有索引读的功能,而列表可以进行 读、改、删

3.4、切片取值

  • 和字符串一样,列表也可以切片
  • 使用语法:列表\[start : end : step],获取列表中在 [start, end) 范围的子列表
  • 注意范围 [start, end) 包含 start,不包含 end
  • step 是步长,设为 n,则每隔 n 个元素获取一次

3.5、切片赋值

💡
赋值的值也必须是列表,否则会报错  TypeError: can only assign an iterable

3.6、关键字 in

通过关键字 in 检查列表中是否包含指定元素,返回 bool 值
not in 则是取反

4、易错点

在 Python 里,一边遍历列表一边删元素是新手最容易踩的坑之一,核心问题是:列表是可变序列,删除操作会立即改变其长度和索引,从而让循环“错位”。下面用 3 个典型场景说明坑点、原因及正确做法。

4.1、漏删 / 跳过元素

原因:第一次删下标 1 的 2 后,后面的元素整体前移,原下标 2 的 2 变成了下标 1,但 for 循环的指针已经走到下标 2 了,于是被跳过。

4.2、IndexError:索引越界

原因:列表长度在循环中不断缩短,而 range(len(lst)) 一开始就把长度固定为 3,当 i=2 时列表只剩 1 个元素,导致越界。

4.3、隐藏的副作用(列表推导式同理)

原因list.remove 会就地修改原列表,列表推导式内部迭代器仍在同一列表上工作,行为完全不可预测。

4.4、✅ 正确姿势

方法
代码示例
说明
倒序遍历
for i in range(len(lst)-1, -1, -1): if cond: del lst[i]
删除不影响未遍历索引
列表拷贝
for x in lst[:]: if cond: lst.remove(x)
遍历副本,修改原列表
生成新列表
lst = [x for x in lst if not cond]
函数式写法,最简洁
filter
lst = list(filter(lambda x: not cond, lst))
与推导式等价

4.5、一句话总结

不要在同一个可变列表上同时进行“遍历指针”和“长度修改”两类操作;要么倒序、要么遍历副本、要么生成新列表。

📝 元组tuple

元组是不可变序列,通常用于储存异构数据的多项集(例如由enumerate() 内置函数所产生的二元组)。
元组也被用于需要同构数据的不可变序列的情况(例如允许存储到set 或dict 的实例)。

1、构造方法:

1.1、字面量括号法(最常用)

细节
说明
逗号是标识符
没有逗号,(42) 只是表达式分组,类型为 int
性能
CPython 在编译期直接生成 BUILD_TUPLE,O(1)。

1.2、内置构造函数 tuple(iterable=())

形参
默认值
复杂度
iterable
()
O(n),n 为元素个数

1.3、生成器 / 推导式转元组

生成器表达式惰性迭代,节省一次中间列表内存。

1.4、序列拆包与星号展开

Python 3.5+ 支持 解包语法,编译器生成 BUILD_TUPLE_UNPACK

1.5、嵌套元组(tuple 嵌套 tuple)

完全合法,用于 坐标点、树节点、多维索引 等场景。

1.6、命名元组(namedtuple)—— 语义元组

仍是 tuple 子类,但带字段名,提升可读性。

1.7、单元素陷阱与布尔陷阱

表达式
结果类型
说明
(42)
int
无逗号,只是括号分组
(42,)
tuple
有逗号,单元素元组
bool(())
False
空元组为假
bool((0,))
True
非空即真

1.8、性能对比

构造方式
时间复杂度
额外内存
备注
字面量 (1, 2, 3)
O(1)
0
字节码直接生成
tuple(iterable)
O(n)
O(n)
需要遍历一次
生成器表达式
O(n)
0(惰性)
无中间列表

1.9、线程安全

元组 不可变,天然线程安全,可作为 dict 键或 set 元素。

2、公共功能

2.1、运算符 +

使用运算符 + 连接多个元组

2.2、运算符 *

使用运算符 * 将元组的元素重复

2.3、索引(下标)取值

2.4、切片取值

  • 和列表一样,元组也可以切片
  • 使用语法:元组\[start : end : step],获取元组中在 [start, end) 范围的子元组
  • 注意范围 [start, end) 包含 start,不包含 end
  • step 是步长,设为 n,则每隔 n 个元素获取一次

2.5、关键字 in

通过关键字 in 检查元组中是否包含指定元素,返回 bool 值
not in 则是取反

📝 range 对象

range 是一个 不可变序列,用来生成 等差整数序列。它既节省内存又支持随机访问,是 for 循环索引切片 最常用的工具之一

1、构造方法

仅限位置参数,无关键字参数。
三种重载在 CPython 中最终都会归一到 (start, stop, step) 三元组。

2、参数语义与默认值

形参
类型
默认值
说明
start
int
0
序列起始值(包含)
stop
int
— 必填
序列终止值(不包含
step
int
1
步长,可为负;不能为 0
  • step为负,序列 递减
  • 所有参数必须是 整数(Python 3 起拒绝 float)。

3、返回值

range 对象lazy):不立即生成列表,仅保存 (start, stop, step)
支持 索引、切片、len()、成员检测且均为 O(1)
要得到列表需显式转换:list(range(...)),复杂度 O(n)

4、行为示例

5、性能与内存

  • 存储仅需 3 个整数(start, stop, step),与长度无关。
  • len(range)计算为 max(0, (stop-start+step-1)//step),O(1)。
  • 遍历速度接近 C 级循环,比生成器更快。

6、常见误区

错误写法
原因
range(5.0)
TypeError: 'float' object cannot be interpreted as an integer
range(5, 10, 0)
ValueError: step argument must not be zero
range(10)[10]
IndexError: range object index out of range

7、==、!= 操作

使用 == 和 != 检测 range 对象是否相等是将其作为序列来比较。也就是说,如果两个 range 对象表示相同的值序列就认为它们是相等的。(请注意比较结果相等的两个 range 对象可能会具有不同的start, stop和step 属性,例如 range(0) == range(2, 1, 3) 而 range(0, 3, 2) == range(0, 4, 2)。)

🤗 总结归纳

 
 
 
  • 开发
  • Python
  • Python数据类型-基础数据类型-str 字符串Python数据类型-基础数据类型-集合类型 --- set
    Loading...
    Catalog
    0%