导读:本期聚焦于小伙伴创作的《Python列表添加元素的常用方法有哪些?详解append/extend/insert等操作》,敬请观看详情。向列表中添加元素是Python编程中最基础的操作之一,但很多人只熟悉append,对其他内置方法和高效技巧了解甚少。append每次只能在末尾追加一个元素,而extend可以批量合并可迭代对象,insert则能在任意位置插入数据。此外,+运算符会生成新列表,切片赋值能在原地实现复杂的插入与替换逻辑。本文以实际场景为例,对比这几种方式的用法、执行效率和内存行为,并指出容易混淆的陷阱,比如用append添加列表会导致嵌套结构,而extend是直接展开。同时还会介绍解包操作和原地修改与生成新列表的选择策略,帮助你在不同需求下做出最优决策。

列表(list)是Python中最常用的内置可变序列类型,几乎所有数据处理任务都离不开它。在循环收集结果、合并多组数据、动态构建结构时,能否正确且高效地向列表添加元素,直接影响代码的可读性和运行性能。Python为列表设计了多种添加元素的手段,每种方法都有自己的适用场景和内部实现细节。理解它们之间的差异,可以避免写出冗余、低效甚至产生bug的代码。

Python列表添加元素的常用方法有哪些?详解append/extend/insert等操作

1. append():在末尾追加单个元素

append()是最高频的列表添加方法,它接受一个参数,并将该参数作为一个整体添加到列表的末尾。操作是原地修改(in-place),返回值为None,不会创建新列表。

# 基本用法
fruits = ['apple', 'banana']
fruits.append('cherry')
print(fruits)  # ['apple', 'banana', 'cherry']

# 添加任何类型的对象
fruits.append(42)
fruits.append([1, 2, 3])  # 整个列表作为一个元素
print(fruits)  # ['apple', 'banana', 'cherry', 42, [1, 2, 3]]

从上面代码可以看出,当使用 append 添加一个列表时,它并不会展开这个列表,而是直接把列表对象本身当作一个新元素。如果需要将另一个序列里的元素逐个添加进去,就要用到 extend

在性能方面,append 的时间复杂度是 O(1)(均摊情况)。Python列表底层使用动态数组实现,当频繁追加元素导致预分配空间不足时,会触发内存重分配并拷贝已有元素,但总体开销很小。因此循环中构建列表时,逐个 append 是非常高效的选择。

2. extend():批量合并可迭代对象

extend() 方法接受一个可迭代对象(如列表、元组、集合、字符串等),会遍历该可迭代对象并将其中的每个元素分别追加到原列表末尾。它同样是原地操作,返回 None

numbers = [1, 2, 3]
numbers.extend([4, 5, 6])   # 列表元素逐个加入
print(numbers)  # [1, 2, 3, 4, 5, 6]

numbers.extend((7, 8))      # 元组也可以
numbers.extend('ab')        # 字符串会被拆分为字符
print(numbers)  # [1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b']

初学者很容易把 appendextend 搞混。一个简单的记忆方法是:append 增加的是“一个对象”,extend 增加的是“一组元素”。如果想把另一个列表的内容合并过来,正确的做法是 list1.extend(list2),而不是 list1.append(list2)

extend 在内部实现上会计算待添加的可迭代对象的长度,一次性预分配足够的内存,因此比用循环 append 每个元素更加高效。当你需要将大量元素一次性合并到现有列表时,优先使用 extend

3. insert():在指定位置插入元素

insert(index, element) 允许在列表的任意索引处插入一个新元素,该位置及之后的所有元素都会向后移动一位。如果 index 超出列表边界,Python会自动将元素放在列表首部(负索引过大时)或尾部(正索引过大时),不会抛出异常。

colors = ['red', 'green', 'blue']
colors.insert(1, 'yellow')  # 在索引1处插入
print(colors)  # ['red', 'yellow', 'green', 'blue']

colors.insert(10, 'purple') # 索引超出,追加到末尾
print(colors)  # ['red', 'yellow', 'green', 'blue', 'purple']

colors.insert(-1, 'black')  # 在倒数第一个位置之前插入
print(colors)  # ['red', 'yellow', 'green', 'blue', 'black', 'purple']

insert 的时间复杂度为 O(n),因为插入点之后的所有元素都需要移动。如果频繁在列表头部插入元素(比如模拟队列的入队操作),性能开销会非常大。这种情况下建议改用 collections.deque,它针对两端操作做了优化。

4. 使用 + 运算符和 * 运算符

加号 + 运算符可以将两个列表拼接起来,返回一个全新的列表,原列表保持不变。这种方式适合需要保留原始数据、只生成一个新组合的场景。

a = [1, 2]
b = [3, 4]
c = a + b
print(c)  # [1, 2, 3, 4]
print(a)  # [1, 2]  原列表未改变

值得注意的是,+ 每次都会创建新对象并拷贝两个列表的所有元素,如果列表很长且频繁拼接,会产生大量内存分配和拷贝开销。对于循环中的累积拼接,更推荐先用普通列表 appendextend,或者使用 list comprehension

乘号 * 也能间接实现“添加重复元素”的效果,但它更适合初始化固定长度的列表。要注意 a = [[0]*5]*3 这种写法会导致内部列表共享引用,一个元素修改会影响到所有行,正确做法是用列表推导式 [[0]*5 for _ in range(3)]

# 初始化一个包含5个0的列表
zeros = [0] * 5
print(zeros)  # [0, 0, 0, 0, 0]

5. 切片赋值:强大的原地修改能力

切片赋值是列表操作中非常灵活的一招,它可以一次性替换、插入或删除一段连续的元素。向列表中插入元素时,可以将某个位置切片为空,然后赋值一个可迭代对象。

nums = [10, 20, 30]
# 在索引1的位置插入两个元素,原来索引1及之后的元素自动后移
nums[1:1] = [15, 18]
print(nums)  # [10, 15, 18, 20, 30]

# 同时可以用切片替换一段元素
nums[2:4] = [100]  # 将索引2和3的元素替换为100
print(nums)  # [10, 15, 100, 30]

切片赋值在解释器内部实现为一系列元素的移动操作,当插入元素较多时,性能介于多次 insert 和一次 extend 之间。虽然它很强大,但代码可读性不如专用方法,在普通插入场景最好还是用 insert,而复杂的原地批量替换可以用切片赋值。

6. 通过解包操作合并列表

Python 3.5 引入的 * 可迭代对象解包操作(PEP 448)可以方便地在列表字面量中展开其他序列,效果类似于 extend,但会生成一个新列表。

part1 = [1, 2]
part2 = [3, 4, 5]
combined = [*part1, *part2, 6, 7]
print(combined)  # [1, 2, 3, 4, 5, 6, 7]

这种方式简洁优雅,不需要调用方法,适合在构造新列表时一次性融合多个来源的数据。因为底层仍然会遍历并拷贝每一个元素,所以时间复杂度为O(n),它不会修改原始列表。

7. 性能对比与使用建议

为了直观感受不同方法的效率差异,可以构造一个简单的测试:分别用 append 循环、extend+ 运算符和切片赋值向列表添加100万个元素。

import timeit

# 准备数据
data = list(range(1000000))

# 测试 extend
def test_extend():
    lst = []
    lst.extend(data)

# 测试循环 append
def test_append_loop():
    lst = []
    for i in data:
        lst.append(i)

# 测试 + 运算符(每次生成新列表,模拟累积拼接)
def test_plus():
    lst = []
    for i in data:
        lst = lst + [i]   # 非常慢,仅作演示

print('extend:', timeit.timeit(test_extend, number=10))
print('append loop:', timeit.timeit(test_append_loop, number=10))
# extend 一般比 append 循环略快,因为减少了函数调用开销
# + 运算符版本因每次拷贝整个列表,性能极差,不推荐

绝大多数场景下,构建列表的推荐做法如下:

  • 逐个收集元素:先创建空列表,在循环中 append
  • 合并另一个序列:使用 extend 或列表解包 [*a, *b]
  • 固定位置插入:偶尔使用 insert,频繁头部插入改用 deque
  • 需要新列表且数据量小:可以直接用 + 或解包,代码更简洁。
  • 复杂原地修改:用切片赋值。

8. 常见陷阱与注意事项

8.1 可变默认参数的副作用

在函数定义中使用可变对象作为默认参数(如空列表)是经典的坑。因为默认参数在函数定义时只计算一次,每次调用都会共享同一个列表对象。

def add_item(item, target=[]):
    target.append(item)
    return target

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2]  非预期的累积

正确做法是将默认值设为 None,在函数体内创建新列表。

8.2 线程安全性

列表的 appendextend 等操作本身是原子的吗?在CPython中,由于全局解释器锁(GIL)的存在,单个列表操作如 append 是线程安全的,但组合多个操作(比如先检查长度再添加)仍可能产生竞态条件。如果确定要跨线程操作列表,建议使用 queue.Queue 或显式加锁。

8.3 复制与引用问题

当列表包含可变对象(如子列表、字典)时,使用 extend 或切片赋值时只拷贝了引用,修改内部对象会影响原数据。若需要完全独立的副本,应使用 copy.deepcopy。例如:

original = [[1, 2], [3, 4]]
new_list = []
new_list.extend(original)
new_list[0][0] = 99
print(original)  # [[99, 2], [3, 4]]  原列表受影响

9. 总结

Python为列表添加元素提供了多种内置操作,每种操作都有其设计意图和性能特征。append 满足日常逐个追加,extend 适合批量合并,insert 处理定点插入,+ 和解包语法生成新列表,切片赋值则提供了原地修改的最大灵活性。选择合适的工具,不仅能让代码更清晰,还能有效提升程序运行效率。在实际项目中,结合数据规模、是否原地修改、内存开销等因素做出权衡,就能写出专业且可靠的Python代码。

Python列表添加元素append修改时间:2026-08-12 03:55:53

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。