Skip to content

列表与元组

列表和元组是 Python 中最常用的序列类型。列表是可变的,元组是不可变的。

列表(List)

创建列表

python
# 创建列表的几种方式
# 空列表
empty_list1 = []
empty_list2 = list()

# 带初始值的列表
numbers = [1, 2, 3, 4, 5]
fruits = ["苹果", "香蕉", "橙子"]
mixed = [1, "hello", 3.14, True]  # 可以混合类型

# 使用 list() 函数
chars = list("Python")  # ['P', 'y', 't', 'h', 'o', 'n']
numbers_from_range = list(range(1, 6))  # [1, 2, 3, 4, 5]

# 列表推导式
squares = [x ** 2 for x in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

访问元素

python
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]

# 索引访问(从 0 开始)
print(fruits[0])   # 苹果
print(fruits[2])   # 橙子
print(fruits[-1])  # 西瓜(最后一个)
print(fruits[-2])  # 葡萄(倒数第二个)

# 切片
print(fruits[1:3])   # ['香蕉', '橙子']
print(fruits[:3])    # ['苹果', '香蕉', '橙子']
print(fruits[2:])    # ['橙子', '葡萄', '西瓜']
print(fruits[::2])   # ['苹果', '橙子', '西瓜'](步长为2)
print(fruits[::-1])  # ['西瓜', '葡萄', '橙子', '香蕉', '苹果'](反转)

# 索引越界
# print(fruits[10])  # IndexError

修改列表

python
numbers = [1, 2, 3, 4, 5]

# 修改元素
numbers[0] = 10
print(numbers)  # [10, 2, 3, 4, 5]

# 切片修改
numbers[1:3] = [20, 30]
print(numbers)  # [10, 20, 30, 4, 5]

# 添加元素
fruits = ["苹果", "香蕉"]

# append():末尾添加
fruits.append("橙子")
print(fruits)  # ['苹果', '香蕉', '橙子']

# insert():指定位置插入
fruits.insert(1, "葡萄")
print(fruits)  # ['苹果', '葡萄', '香蕉', '橙子']

# extend():添加多个元素
fruits.extend(["西瓜", "草莓"])
print(fruits)  # ['苹果', '葡萄', '香蕉', '橙子', '西瓜', '草莓']

# + 运算符
more_fruits = fruits + ["芒果", "樱桃"]
print(more_fruits)

删除元素

python
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]

# del 语句:按索引删除
del fruits[1]
print(fruits)  # ['苹果', '橙子', '葡萄', '西瓜']

# pop():删除并返回元素
removed = fruits.pop()  # 默认删除最后一个
print(f"删除了:{removed}")
print(fruits)  # ['苹果', '橙子', '葡萄']

removed = fruits.pop(1)  # 删除指定索引
print(f"删除了:{removed}")

# remove():按值删除
fruits = ["苹果", "香蕉", "橙子", "香蕉"]
fruits.remove("香蕉")  # 只删除第一个匹配项
print(fruits)  # ['苹果', '橙子', '香蕉']

# clear():清空列表
fruits.clear()
print(fruits)  # []

列表方法

python
numbers = [3, 1, 4, 1, 5, 9, 2, 6]

# 排序
# sort():原地排序
numbers.sort()
print(numbers)  # [1, 1, 2, 3, 4, 5, 6, 9]

numbers.sort(reverse=True)  # 降序
print(numbers)

# sorted():返回新列表
original = [3, 1, 4, 1, 5]
sorted_list = sorted(original)
print(f"原列表:{original}")
print(f"排序后:{sorted_list}")

# 反转
numbers = [1, 2, 3, 4, 5]
numbers.reverse()
print(numbers)  # [5, 4, 3, 2, 1]

# 查找
fruits = ["苹果", "香蕉", "橙子", "香蕉"]
print(fruits.index("橙子"))    # 2(索引)
# print(fruits.index("葡萄"))  # ValueError

print(fruits.count("香蕉"))    # 2(出现次数)

# 复制
original = [1, 2, 3]
copy1 = original.copy()
copy2 = original[:]
copy3 = list(original)

# 判断元素是否存在
print("香蕉" in fruits)   # True
print("葡萄" in fruits)   # False

列表嵌套

python
# 二维列表
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 访问元素
print(matrix[0])      # [1, 2, 3]
print(matrix[0][1])   # 2

# 遍历二维列表
for row in matrix:
    for item in row:
        print(item, end=" ")
    print()

# 使用推导式创建二维列表
grid = [[0 for _ in range(3)] for _ in range(3)]
print(grid)  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 转置矩阵
transposed = [[row[i] for row in matrix] for i in range(3)]
print(transposed)

元组(Tuple)

创建元组

python
# 创建元组
# 空元组
empty_tuple = ()
empty_tuple2 = tuple()

# 带值的元组
coordinates = (10, 20)
colors = ("红", "绿", "蓝")

# 单元素元组(注意逗号)
single = (1,)  # 必须有逗号
not_tuple = (1)  # 这只是数字 1

# 不加括号也可以
weekend = "周六", "周日"
print(type(weekend))  # <class 'tuple'>

# 使用 tuple() 函数
chars = tuple("Python")
print(chars)  # ('P', 'y', 't', 'h', 'o', 'n')

numbers = tuple(range(1, 6))
print(numbers)  # (1, 2, 3, 4, 5)

访问元素

python
colors = ("红", "绿", "蓝", "黄", "紫")

# 索引访问
print(colors[0])   # 红
print(colors[-1])  # 紫

# 切片
print(colors[1:3])   # ('绿', '蓝')
print(colors[::-1])  # ('紫', '黄', '蓝', '绿', '红')

# 解包
r, g, b = ("红", "绿", "蓝")
print(r, g, b)

# 扩展解包
first, *rest = colors
print(first)  # 红
print(rest)   # ['绿', '蓝', '黄', '紫']

head, *middle, tail = colors
print(head)    # 红
print(middle)  # ['绿', '蓝', '黄']
print(tail)    # 紫

元组不可变

python
coordinates = (10, 20)

# 元组不可修改
# coordinates[0] = 15  # TypeError

# 但可以重新赋值
coordinates = (15, 25)  # 创建新元组

# 元组中的可变元素可以修改
nested = ([1, 2], [3, 4])
nested[0].append(3)  # 可以修改列表元素
print(nested)  # ([1, 2, 3], [3, 4])

# 连接和重复
t1 = (1, 2)
t2 = (3, 4)
print(t1 + t2)   # (1, 2, 3, 4)
print(t1 * 3)    # (1, 2, 1, 2, 1, 2)

元组方法

python
numbers = (1, 2, 3, 2, 4, 2, 5)

# count():统计出现次数
print(numbers.count(2))  # 3

# index():查找索引
print(numbers.index(3))  # 2
print(numbers.index(2, 2))  # 从索引2开始查找,返回3

# 判断元素
print(3 in numbers)   # True
print(6 in numbers)   # False

# 长度
print(len(numbers))   # 7

# 最大最小值
print(max(numbers))   # 5
print(min(numbers))   # 1

# 求和
print(sum(numbers))   # 19

元组的应用

python
# 函数返回多个值
def get_stats(numbers):
    """返回最小值、最大值和平均值"""
    return min(numbers), max(numbers), sum(numbers) / len(numbers)

minimum, maximum, average = get_stats([1, 2, 3, 4, 5])
print(f"最小值:{minimum},最大值:{maximum},平均值:{average}")

# 格式化字符串
point = (3, 4)
print(f"坐标:{point}")

# 字典的键(列表不能作为键)
locations = {
    (0, 0): "原点",
    (1, 0): "x轴上",
    (0, 1): "y轴上"
}
print(locations[(0, 0)])

# 交换变量
a, b = 10, 20
a, b = b, a  # 使用元组解包
print(a, b)  # 20 10

# 命名元组
from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)  # 3 4
print(p[0], p[1])  # 3 4

列表 vs 元组

text
┌─────────────────────────────────────────────────────────────────┐
│                    列表 vs 元组                                   │
├─────────────────────────────────────────────────────────────────┤
│        特性         │      列表        │     元组                │
├─────────────────────────────────────────────────────────────────┤
│  可变性             │       可变       │      不可变             │
│  语法               │      [1, 2]      │      (1, 2)             │
│  方法               │       多         │       少                │
│  性能               │       较慢       │      较快               │
│  内存占用           │       较大       │      较小               │
│  作为字典键         │       不能       │       能                │
│  使用场景           │    需要修改      │    不需要修改           │
└─────────────────────────────────────────────────────────────────┘
python
import sys

# 内存占用对比
lst = [1, 2, 3, 4, 5]
tpl = (1, 2, 3, 4, 5)

print(f"列表占用:{sys.getsizeof(lst)} 字节")
print(f"元组占用:{sys.getsizeof(tpl)} 字节")

# 性能对比
import timeit

list_time = timeit.timeit("[1, 2, 3, 4, 5]", number=1000000)
tuple_time = timeit.timeit("(1, 2, 3, 4, 5)", number=1000000)

print(f"列表创建时间:{list_time:.4f}")
print(f"元组创建时间:{tuple_time:.4f}")

实际应用示例

列表操作

python
# 数据处理
scores = [85, 92, 78, 90, 88, 76, 95, 82]

# 统计分析
average = sum(scores) / len(scores)
highest = max(scores)
lowest = min(scores)

print(f"平均分:{average:.1f}")
print(f"最高分:{highest}")
print(f"最低分:{lowest}")

# 筛选及格的成绩
passing = [s for s in scores if s >= 80]
print(f"及格成绩:{passing}")

# 成绩分级
grades = [
    "优秀" if s >= 90 else
    "良好" if s >= 80 else
    "及格" if s >= 60 else "不及格"
    for s in scores
]
print(f"等级:{grades}")

# 排序并获取前3名
top3 = sorted(scores, reverse=True)[:3]
print(f"前三名:{top3}")

# 去重
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = list(set(numbers))
print(f"去重后:{unique}")

元组应用

python
# 表示固定数据
# 一周七天
WEEKDAYS = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")

# 方向
DIRECTIONS = ("北", "东", "南", "西")

# 坐标点
points = [(0, 0), (1, 2), (3, 4), (5, 6)]

# 计算两点距离
def distance(p1, p2):
    """计算两点之间的距离"""
    return ((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2) ** 0.5

print(f"距离:{distance((0, 0), (3, 4)):.2f}")

# 遍历坐标
for x, y in points:
    print(f"({x}, {y})")

小结

本章我们学习了:

  • 列表创建:[]、list()、列表推导式
  • 列表操作:访问、修改、添加、删除
  • 列表方法:sort()、reverse()、index()、count() 等
  • 元组创建:()、tuple()、逗号
  • 元组特性:不可变、可哈希
  • 元组应用:函数返回值、字典键、命名元组

下一章,我们将学习 字典与集合,了解 Python 中的映射和集合类型。