飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 Python简介

    • Python是什么
    • 安装与运行
    • 交互式解释器
    • 注释与编码规范
  • 第2章 变量与数据类型

    • 变量与对象
    • 整数 int
    • 浮点数 float
    • 复数 complex
    • 布尔值 bool
    • 字符串 str
    • 空值 None
    • 类型转换
  • 第3章 运算符与表达式

    • 算术运算符
    • 比较运算符
    • 赋值运算符
    • 逻辑运算符
    • 位运算符
    • 身份与成员运算符
    • 海象运算符
    • 运算符优先级
  • 第4章 流程控制

    • if 语句
    • if-else 语句
    • if-elif-else 语句
    • match-case 语句
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 函数
    • break 与 continue
    • 循环的 else 子句
    • pass 语句
  • 第5章 数据结构

    • 列表创建与索引
    • 列表方法
    • 列表推导式
    • 元组
    • 序列解包
    • 集合
    • 字典创建与访问
    • 字典方法
    • 字典推导式
    • range 对象
  • 第6章 函数

    • 定义函数
    • 位置参数与关键字参数
    • 默认参数
    • 可变参数
    • 解包实参
    • 函数返回值
    • lambda 表达式
    • 文档字符串与注解
    • 作用域与命名空间
    • global 与 nonlocal
  • 第7章 模块与包

    • 模块导入
    • 模块搜索路径
    • 包与相对导入
    • 标准库概览
  • 第8章 文件与输入输出

    • 文件读写
    • 上下文管理器
    • 字符串格式化
    • JSON 与 CSV
  • 第9章 面向对象

    • 类与对象
    • 方法
    • 实例变量与类变量
    • 私有变量
    • 继承
    • 多重继承
    • 魔术方法
    • 属性装饰器
    • 数据类 dataclass
  • 第10章 异常处理

    • 语法错误与异常
    • try-except
    • 异常链与 raise
    • 清理操作
    • 自定义异常
  • 第11章 迭代器与生成器

    • 迭代器协议
    • 生成器
    • 生成器表达式
    • 迭代工具
  • 第12章 高级特性

    • 装饰器
    • 函数式编程
  • 第13章 工程实践

    • 测试与调试
    • 代码质量
    • 虚拟环境

列表创建与索引

列表是 Python 中最常用的可变序列类型,能够容纳任意类型的对象,并且支持动态增删。理解列表的创建方式和索引机制,是掌握 Python 数据结构的基础。

创建列表

最直接的方式是使用方括号字面量,元素之间用逗号分隔:

numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True, None]  # 类型可以混用
nested = [[1, 2], [3, 4], [5, 6]]      # 嵌套列表

也可以通过 list() 构造函数从其他可迭代对象创建列表。字符串会被拆成单个字符,range 对象会展开为具体数字:

chars = list("abc")          # ['a', 'b', 'c']
digits = list(range(5))     # [0, 1, 2, 3, 4]
empty = list()              # []

创建空列表有两种等价写法:[] 和 list()。对于已知元素的列表,字面量写法更简洁;当需要转换生成器、元组或字典键时,list() 构造函数必不可少。

索引访问

列表中的每个元素都有唯一的整数索引,从 0 开始计数。正向索引从左往右,负向索引从右往左:

fruits = ["apple", "banana", "cherry", "date"]

fruits[0]    # 'apple',第一个元素
fruits[2]    # 'cherry',第三个元素
fruits[-1]   # 'date',最后一个元素
fruits[-2]   # 'cherry',倒数第二个

索引访问在越界时会立即抛出 IndexError,这与切片的容错行为形成鲜明对比:

fruits[10]   # IndexError: list index out of range
fruits[-10]  # IndexError: list index out of range

切片操作

切片通过 [start:stop:step] 语法提取子序列。start 包含在内,stop 不包含,即左闭右开区间。三个参数均可省略:省略 start 默认为 0,省略 stop 默认为列表长度,省略 step 默认为 1:

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

nums[2:5]     # [2, 3, 4],索引2到4
nums[:4]      # [0, 1, 2, 3],从头开始
nums[6:]      # [6, 7, 8, 9],到末尾结束
nums[:]       # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],完整拷贝
nums[::2]     # [0, 2, 4, 6, 8],每隔一个取一个
nums[1::2]    # [1, 3, 5, 7, 9],从1开始隔一个取

切片具有容错性:索引超出范围不会报错,而是自动截断到有效区间:

nums[5:100]   # [5, 6, 7, 8, 9],不会报错
nums[20:30]  # [],返回空列表
nums[-100:2] # [0, 1],负数过大也被截断

负步长切片可以实现反转效果,这是 Python 中反转序列最惯用的写法:

nums[::-1]    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0],完全反转
nums[8:2:-1]  # [8, 7, 6, 5, 4, 3],从8倒着取到3
nums[2:8:-1]  # [],start < stop 且步长为负,结果为空

注意 nums[8:2:-1] 与 nums[2:8:-1] 的区别:前者 start > stop 配合负步长,能正常提取;后者方向矛盾,结果为空列表。

切片赋值

切片不仅可以读取,还可以用于赋值,这是修改列表最灵活的方式之一。赋值右侧必须是可迭代对象:

nums = [0, 1, 2, 3, 4, 5]

# 替换一段
nums[1:4] = [10, 20, 30]
# nums 变为 [0, 10, 20, 30, 4, 5]

# 插入元素(用长度不同的可迭代对象)
nums[2:2] = [99, 88]  # 在索引2处插入
# nums 变为 [0, 10, 99, 88, 20, 30, 4, 5]

# 删除元素(赋值为空列表)
nums[3:5] = []
# nums 变为 [0, 10, 99, 30, 4, 5]

# 清空整个列表
nums[:] = []
# nums 变为 []

切片赋值会原地修改列表,不会创建新列表对象。nums[:] 与 nums 的区别在于,前者保持原列表对象的标识不变,只是清空内容;后者让变量指向一个全新的空列表。

带步长的切片赋值要求右侧元素数量与切片选中的元素数量严格相等,否则会报错:

nums = [0, 1, 2, 3, 4, 5]
nums[::2] = [10, 20, 30]   # 选中 0,2,4 共3个,右侧也是3个,成功
# nums 变为 [10, 1, 20, 3, 30, 5]

nums[::2] = [10, 20]       # ValueError: 左侧选中3个,右侧只有2个

深浅拷贝

将列表赋值给新变量,只是让两个变量指向同一个对象,修改会互相影响:

a = [1, 2, 3]
b = a
b[0] = 99
print(a)  # [99, 2, 3],a 也被改了
print(a is b)  # True,同一对象

切片 [:] 或 list.copy() 创建的是浅拷贝:外层列表是新对象,但内部元素仍共享引用:

import copy

a = [[1, 2], [3, 4]]
b = a[:]          # 浅拷贝
c = copy.deepcopy(a)  # 深拷贝

b[0][0] = 99
print(a[0])       # [99, 2],浅拷贝内部仍共享
print(c[0])       # [1, 2],深拷贝完全独立
print(a is b)     # False,外层是不同对象

对于一维列表且元素均为不可变类型时,浅拷贝已足够安全;一旦列表嵌套或包含可变对象,必须使用 copy.deepcopy() 才能彻底隔离。

下一页
列表方法