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

如何让Python列表正确存储每次用户输入生成的独立字典

问题描述

编写个人预算统计Python脚本时预期实现逻辑:

  • 第一步接收用户输入的净收入
  • 循环询问用户是否添加支出项
  • 每次循环收集三类信息:支出名称描述、预算金额、支出类型(需要/想要/储蓄),存入字典后追加到budget列表中

实际运行出现异常:每次循环更新字典内容后,列表中之前存储的所有字典条目都会被新输入的内容覆盖,最终输出的列表内所有元素均为最后一次输入的字典内容。最初误将字典追加操作写为budget.update(),修正为budget.append()后问题仍然存在。

问题复现代码
#line used to accept user's net pay
net_income = float(input("Please enter your net income: "))

#line used to query if user wants to input budgeted line item
add_exp_item= input("Do you want to add an expenditure item (yes or no): ").lower()

#intialization of dictionary and list used to store user input 
budget = []
budget_listItem = {}

#loop used to continuously query for budgeted expense item
while True:
    #line used to store description of expense
    d= input("Enter name description of expense: ")
    
    #line used to store numerical value of expense
    a = float(input("Enter cost/budgeted amount: "))
   
    #line used to store the type of expense 
    t = input("Enter category type that such as whether it is a want, need, saving: ")
    
    #line used to store all user input in dictionary 
    budget_listItem.update({'description': d, 'amount': a, 'type': t})
    
    #testing line to to see what is stored in dictionary
    print(budget_listItem)

    #line used to store each expense line (each dictionary) in a list
    budget.append(budget_listItem)
  
    #testing line to check what is in list of dictionaries
    print(budget)
    
    #line used to query if user wants to enter another line item
    add_exp_item= input("Do you want to add an expenditure item (yes or no): ").lower()
    print("*************************************************** \n")

    #bool used to break out of loop if user no longer wants to enter line items
    if add_exp_item == "no":
        break

print("\n \n")

#final print of list of dictionaries
print(budget)
问题根因

Python中字典属于可变引用类型,代码在循环外仅初始化了1次budget_listItem字典,整个循环运行过程中操作的始终是同一个内存地址的字典对象。
执行budget.append(budget_listItem)时,追加到列表中的不是字典内容的独立副本,而是该字典的内存引用——也就是说列表里存储的所有条目本质上都指向同一个字典对象,后续调用budget_listItem.update()修改字典内容时,所有指向该对象的列表条目会同步更新为最新值,最终表现为所有列表元素都和最后一次输入的内容一致。

修复方案

二选一即可解决问题:

  • 将budget_listItem = {}的字典初始化逻辑移到while True循环内部,每次处理新支出项时都创建一个全新的独立字典,保证每次追加到列表的都是互不干扰的新对象。
  • 保留循环外的字典初始化逻辑,追加时传入字典的浅拷贝,将追加语句修改为budget.append(budget_listItem.copy()),这样每次存入列表的是当前字典内容的独立快照,后续修改原字典不会影响已经存入列表的内容。

修正后核心代码参考(采用第一种方案)

net_income = float(input("Please enter your net income: "))
add_exp_item= input("Do you want to add an expenditure item (yes or no): ").lower()
budget = []

while True:
    # 每次循环新建独立字典存储当前支出
    budget_listItem = {}
    d= input("Enter name description of expense: ")
    a = float(input("Enter cost/budgeted amount: "))
    t = input("Enter category type that such as whether it is a want, need, saving: ")
    budget_listItem.update({'description': d, 'amount': a, 'type': t})
    budget.append(budget_listItem)
    
    add_exp_item= input("Do you want to add an expenditure item (yes or no): ").lower()
    print("*************************************************** \n")
    if add_exp_item == "no":
        break

print(budget)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:33:28