序列
大约 2 分钟
前奏
按数据结构划分
- Sequence(序列):list、tuple、str、bytes、range,支持下标索引,按位置存取。
- Mapping(映射):dict,key-value 结构,3.7 之后保留插入顺序,但不属于序列。
- Set(集合):set,无索引、元素唯一,不属于序列。
所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们
为什么要这么划分?
- list 列表:可变数组。底层是一块连续内存,但会预留冗余空间。可以增删改元素。代价:插入删除中间元素要挪动后面的数据。适合经常改动、按序号拿数据的场景。
- tuple 元组:声明之后不可修改。内存分配一次性固定,不会额外预留空间。因为不可变,它能做字典的 key、可以 hash。底层没有扩容、没有修改的开销。
类比 C# 固定长度数组,但 tuple 不止存单一类型,它可以打包一组不同类型的值,用来表示 “一组不会变的数据”,比如坐标 (x,y)。一旦创建就不允许修改,防止代码里无意篡改,保证数据安全。
- dict 字典:哈希表,key-value。不靠顺序索引,靠 key 直接定位,查找速度很快。适合需要根据名字 / 标识去取值,不关心先后顺序的场景。
- set 集合:本质就是只有 key、不带 value 的字典,自动去重。专门用来判断元素是否存在、求交集差集。
核心一句话:把 “会不会变” 作为第一区分条件。
- 数据确定不会改动,就用 tuple。解释器可以做内存优化,还能哈希;
- 数据需要频繁增删,就用 list;
- 需要按键查询,用 dict;
- 需要去重、成员判断,用 set。
C、C# 里面要自己手动区分可变 / 不可变、自己管理内存。Python 直接把这些场景封装成不同容器,让开发者根据数据的行为去选型,而不是自己手动控制内存。
序列正篇
序列索引:
序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增,除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始
提示
注意,在使用负值作为列序中各元素的索引值时,是从 -1 开始,而不是从 0 开始
序列切片
切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。
