You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环中追加字典至列表异常的原因及解决方法

问题分析与解决:字典引用导致的列表元素异常变化

你的代码

class Result:

    def __init__(self):
        self.limit = 10
        self.params_with_error = []

    def get_result(self, offset_range):
        qs = {'limit': self.limit}
        for chunk in range(offset_range):
            print(f'chunk: {chunk}')
            print(f'__Params_with_error__: {self.params_with_error}')

            qs.update({'offset': chunk * self.limit})

            if chunk in (5, 7):
                print('IF condition')
                self.params_with_error.append(qs)
        print(f'Result param: {self.params_with_error}')

result = Result()
result.get_result(10)

实际输出

chunk: 0
__Params_with_error__: []
chunk: 1
__Params_with_error__: []
chunk: 2
__Params_with_error__: []
chunk: 3
__Params_with_error__: []
chunk: 4
__Params_with_error__: []
chunk: 5
__Params_with_error__: []
IF condition
chunk: 6
__Params_with_error__: [{'limit': 10, 'offset': 50}]
chunk: 7
__Params_with_error__: [{'limit': 10, 'offset': 60}]
IF condition
chunk: 8
__Params_with_error__: [{'limit': 10, 'offset': 70}, {'limit': 10, 'offset': 70}]
chunk: 9
__Params_with_error__: [{'limit': 10, 'offset': 80}, {'limit': 10, 'offset': 80}]
Result param: [{'limit': 10, 'offset': 90}, {'limit': 10, 'offset': 90}]

你的预期输出

[{'limit': 10, 'offset': 50}, {'limit': 10, 'offset': 70}]

为什么会出现这种情况?

核心原因是Python里的字典是可变对象:你在循环外只创建了一个qs字典,之后每次qs.update()都是修改同一个字典对象,而self.params_with_error.append(qs)只是把这个字典的引用添加到列表里,不是复制一份新字典。

直白点说:列表里的两个元素其实指向同一个字典。后续循环中每次修改qs的offset,都会同时影响列表里的这两个引用,直到最后一次循环(chunk=9)把offset改成了90,所以列表里的两个元素最终都显示90。

怎么得到预期结果?

有两种简单有效的解决方法:

  • 方法1:每次append时复制字典副本
    把self.params_with_error.append(qs)改成self.params_with_error.append(qs.copy()),这样每次添加的都是当前qs的独立副本,后续修改原qs不会影响已经存入列表的内容。

    修改后的代码片段:

    if chunk in (5, 7):
        print('IF condition')
        self.params_with_error.append(qs.copy())
    
  • 方法2:把字典定义放到循环内部
    每次循环都创建一个新的qs字典,这样每次append的都是完全独立的字典对象:

    def get_result(self, offset_range):
        for chunk in range(offset_range):
            print(f'chunk: {chunk}')
            print(f'__Params_with_error__: {self.params_with_error}')
            
            # 每次循环新建字典
            qs = {'limit': self.limit, 'offset': chunk * self.limit}
    
            if chunk in (5, 7):
                print('IF condition')
                self.params_with_error.append(qs)
        print(f'Result param: {self.params_with_error}')
    

两种方法都能得到你预期的输出结果。


内容的提问来源于stack exchange,提问作者Jekson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:31:06