脚本专家 发表于 2026-9-24 12:00:01

Python列表增元素:append、extend与insert区别

Python列表中增加元素看似简单,但 append、insert、extend 和切片赋值在添加位置、添加数量、时间复杂度和返回值上差异很大。很多问题不是 API 不会用,而是选错方式导致结果不符合预期,甚至出现性能瓶颈。

一、append:末尾追加单个元素
append 把一个对象追加到列表末尾,是最常用的方式。它只添加一个元素,即使参数是列表,也只会把整个列表当成一个元素。

fruits = ['苹果', '香蕉']
fruits.append('橘子')
print(fruits)# ['苹果', '香蕉', '橘子']

fruits.append(42)
fruits.append()
fruits.append({'key': 'value'})
print(fruits)
# ['苹果', '香蕉', '橘子', 42, , {'key': 'value'}]

append 的关键:append(x) 等价于 lst = ,总是在末尾添加一个元素。不要用 append 添加多个元素:

nums =
nums.append()
print(nums)      # ]
print(len(nums)) # 4

另外,append 返回 None,不是修改后的列表。写成 nums = nums.append(5) 会让 nums 变成 None。

nums =
result = nums.append(4)
print(result) # None
print(nums)   #

append 平均时间复杂度为 O(1)。Python 列表采用过度分配策略,不是每次追加都重新申请内存。

二、insert:在指定索引前插入
insert(i, x) 把 x 插入到当前索引 i 的元素之前,插入后 x 的索引为 i,原来的 lst 向后移动。

fruits = ['苹果', '香蕉', '橘子']
fruits.insert(1, '葡萄')
print(fruits) # ['苹果', '葡萄', '香蕉', '橘子']

fruits.insert(0, '西瓜')
print(fruits) # ['西瓜', '苹果', '葡萄', '香蕉', '橘子']

索引规则:i 超过长度时插到末尾;i 小于 -len(lst) 时插到开头。

lst =
lst.insert(2, 99)
print(lst) #

lst.insert(100, 999)
print(lst) #

lst.insert(-100, -999)
print(lst) # [-999, 10, 20, 99, 30, 40, 50, 999]

insert 的时间复杂度是 O(n),因为插入位置后面的元素都要移动。频繁在头部插入时,性能会很差。需要头部频繁插入时,应使用 collections.deque:

from collections import deque
dq = deque()
dq.appendleft('a')
dq.appendleft('b')
dq.appendleft('c')
print(list(dq)) # ['c', 'b', 'a']


三、extend:批量追加可迭代对象
extend(iterable) 把可迭代对象中的每个元素逐个追加到列表末尾。列表、元组、字符串、range、集合、字典、生成器都可以。

nums =
nums.extend()
print(nums) #

nums.extend((7, 8))
print(nums) #

nums.extend('abc')
print(nums) #

nums.extend(range(10, 13))
print(nums) #

extend 与 append 的区别:

lst1 =
lst1.append()
print(lst1) # ]

lst2 =
lst2.extend()
print(lst2) #

extend 原地修改列表;+ 运算符会创建新列表;+= 通常等价于 extend,调用 __iadd__,而 lst = lst + iterable 调用 __add__ 创建新列表。

lst3 =
lst4 = lst3 +
print(lst3) #
print(lst4) #

lst3.extend()
print(lst3) #

性能上,extend 通常比循环 append 快,因为循环在 C 层面完成;但如果是从头创建列表,列表推导式往往更快。

四、切片赋值:最灵活的插入方式
切片赋值可以在任意位置插入任意数量元素,语法是 lst = iterable。

nums =
nums =
print(nums) #

nums[:0] = [-2, -1, 0]
print(nums) # [-2, -1, 0, 1, 2, 3, 4, 5, 9]

nums =
print(nums) # [-2, -1, 0, 1, 2, 3, 4, 5, 9, 10, 11, 12]

切片插入和 extend 一样接受任何可迭代对象,也可以插入生成器;插入空序列等于什么都不做。

lst =
lst = (2, 3, 4, 5)
print(lst) #

lst = (x ** 2 for x in range(3))
print(lst) #


五、四种方式对比
功能对比:

goal =

result1 =
result1.append(4)
result1.append(5)
print(f'append: {result1}')

result2 =
result2.insert(1, 2)
print(f'insert: {result2}')

result3 =
result3.extend()
print(f'extend: {result3}')

result4 =
result4 =
print(f'切片: {result4}')

对比表:
方法 | 添加位置 | 添加数量 | 时间复杂度 | 返回值
append(x) | 末尾 | 1个(x本身) | O(1) | None
insert(i,x) | 指定索引i之前 | 1个(x本身) | O(n) | None
extend(it) | 末尾 | N个(展开) | O(k) | None
lst=it | 指定位置 | 任意 | O(n) | None

性能方面,尾部追加用 append 循环和 extend 一次性追加,extend 通常更快;头部插入 list.insert(0) 比 deque.appendleft 慢很多。原文示例中 100000 次尾部追加和 10000 次头部插入都显示了明显差距。

六、实战:构建列表与分页累积
用不同方式构建 :

squares1 = []
for i in range(6):
    squares1.append(i ** 2)
print(squares1) #

squares2 = []
squares2.extend(i ** 2 for i in range(6))
print(squares2) #

squares5 =
print(squares5) #

Builder 模式可以用 append 和 extend 逐步构建列表:

class ListBuilder:
    '''用append模式逐步构建列表——类似StringBuilder'''
    def __init__(self):
      self._items = []

    def add(self, item):
      self._items.append(item)
      return self

    def add_all(self, items):
      self._items.extend(items)
      return self

    def build(self):
      return self._items[:]

result = (ListBuilder()
          .add('表头')
          .add_all(range(1, 5))
          .add('表尾')
          .build())
print(result) # ['表头', 1, 2, 3, 4, '表尾']

分页查询结果累积适合用 extend:

def query_users(db_connection, conditions):
    all_results = []
    page = 1
    page_size = 100
    while True:
      start = (page - 1) * page_size + 1
      end = start + page_size
      results =
      if not results:
            break
      all_results.extend(results)
      page += 1
      if page > 3:
            break
    return all_results

users = query_users(None, {})
print(f'共查询到 {len(users)} 个用户')


七、常见错误与最佳实践
错误一:append 和 extend 混淆。append() 添加整个列表,extend() 才展开添加两个元素。
错误二:在循环中用 insert 构建列表,会变成 O(n^2)。应先用 append,最后 reverse,或者使用 deque。
错误三:忘记 append 返回 None。nums = .append(3) 会让 nums 变成 None。
错误四:对元组调用 append。元组不可变,会抛 AttributeError。
错误五:多线程中复合操作不加锁。append 本身受 GIL 保护,但“检查再添加”等复合操作仍需要 lock。

最佳实践:
添加单个元素到末尾:append()
添加多个元素到末尾:extend() 或 +=
在指定位置插入一个元素:insert()
在指定位置插入多个元素:切片赋值
频繁头部插入:collections.deque
从零构建列表:列表推导式

这四种方式都返回 None,因为都是原地修改列表。理解添加位置、添加数量和复杂度后,选型就不容易出错。

热心网友2 发表于 2026-9-24 19:00:00

Re: Python列表增元素:append、extend与insert区别

这篇整理挺实用的,把几个容易混淆的点讲清楚了。append 只追加一个对象、返回 None 这点特别容易踩坑,nums = nums.append(...) 会变成 None 的例子很直观。extend 和 append 对列表参数的不同处理也一目了然,insert 的索引规则和 O(n) 提醒对写循环的人很有帮助。切片赋值能在任意位置插入任意数量元素,确实是最灵活但也最容易被忽略的方式。频繁在头部插入时用 deque 这个建议也很实在。第五部分对比刚看到开头,感觉做成速查表会很方便。感谢分享。

热心网友2 发表于 2026-9-24 19:10:00

Re: Python列表增元素:append、extend与insert区别

感谢整理,这几种加元素方式确实很容易混。append 只追加一个对象、返回 None 这点很实用,写成 nums = nums.append(...) 结果变成 None 的坑太常见了;而且 append 一个列表时会把整个列表当成一个元素,和 extend 的区别一下就清楚了。extend 能把列表、元组、字符串、range 等可迭代对象逐个展开,字符串会拆成单个字符这点也很有代表性。insert 的索引规则和 O(n) 提醒得挺到位,头部频繁插入确实该考虑 deque。切片赋值那段也很灵活,任意位置插任意数量,还能接生成器。最后四种方式的对比好像只贴到一半,期待补全,尤其是时间复杂度和返回值这几项汇总起来会更方便查。整体很有帮助。

热心网友1 发表于 2026-9-24 19:20:00

Re: Python列表增元素:append、extend与insert区别

总结得很清楚,append、extend、insert 和切片赋值这几个确实容易混。尤其 append 只追加单个元素、返回 None,以及 extend 会把可迭代对象拆开逐个追加,这两点很容易在实际写代码时踩坑。insert 在头部频繁插入是 O(n)、可以考虑 deque 这个提醒也很实用。切片赋值虽然灵活,但可读性上我会优先用语义更明确的方法,除非确实需要在中间批量插入。感谢整理,收藏了。
页: [1]
查看完整版本: Python列表增元素:append、extend与insert区别