Python dict的值在我将其传递给函数时会发生变化,而它们不应该';T
最近学习python时,我有一个程序,它获取一个dict列表(列表中的每个dict都有其他dict的重复键) 然后它将其传递给一个函数,该函数的任务是聚合值中的数据并返回一个dict,但是,当我在函数调用后再次访问原始dict时,它已使用单个dict中的值进行了更新,我看不到正在执行该操作的方法中的任何代码部分,已经被困了几个小时了 这是我的密码:Python dict的值在我将其传递给函数时会发生变化,而它们不应该';T,python,dictionary,python-2.x,Python,Dictionary,Python 2.x,最近学习python时,我有一个程序,它获取一个dict列表(列表中的每个dict都有其他dict的重复键) 然后它将其传递给一个函数,该函数的任务是聚合值中的数据并返回一个dict,但是,当我在函数调用后再次访问原始dict时,它已使用单个dict中的值进行了更新,我看不到正在执行该操作的方法中的任何代码部分,已经被困了几个小时了 这是我的密码: #!/usr/bin/env python import ast def process_visitor_stats_list(original_
#!/usr/bin/env python
import ast
def process_visitor_stats_list(original_list):
temp_original_list = original_list[:] # attempt to copy original list so it doesnt get changed
new_dict = {} # this will store each unique key in dict along with the sum of its values
for line in temp_original_list:
for key in line:
if(key not in new_dict): # checks if key is in new_dict, adds it if not and adds a value which tracks how often the key occurs
new_dict[key] = line[key]
new_dict[key].append(1) # it also adds another number to the value, which stores the amount of times it was in the original list of dicts
else:
new_dict[key][0] += float(line[key][0]) # if key is already in dict, it sums its values
new_dict[key][1] += float(line[key][1])
new_dict[key][2] += 1
return new_dict
if __name__ == "__main__":
original_list_of_dicts = [] # this will store my list of dicts
line1 = "{'entry1': [4.0, 2.0], 'entry2': [592.0, 40.0], 'entry3': [5247044.0, 1093776.0], 'entry4': [1235.0, 82.0]}"
line2 = "{'entry1': [26260.0, 8262.0], 'entry2': [2.0, 0.0], 'entry3': [1207.0, 142.0], 'entry4': [382992.0, 67362.0]}"
line3 = "{'entry1': [57486.0, 16199.0], 'entry2': [6.0, 3.0], 'entry3': [280.0, 16.0]}"
original_list_of_dicts.append(ast.literal_eval(line1)) # adds each line to the list and casts them as dicts
original_list_of_dicts.append(ast.literal_eval(line2))
original_list_of_dicts.append(ast.literal_eval(line3))
print "original list of dicts before method call"
for line in original_list_of_dicts: # prints out each entry in the list of dicts
for key in line:
print key + str(line[key])
print '\n'
new_dict = process_visitor_stats_list(original_list_of_dicts) # calls the method to process the original list of dicts
print '\n' # this should return a single dict list with aggregate data
print "original list of dicts after method call"
for line in original_list_of_dicts: # however when i go to access the original dict, its values have been changed
for key in line:
print key + str(line[key])
复制列表时:
temp_original_list = original_list[:]
import copy
temp_original_list = copy.deepcopy(original_list)
只进行浅层复制,即新列表包含对原始列表中相同对象的引用。由于列表中的对象是可变字典,因此需要对列表进行深度复制:
temp_original_list = original_list[:]
import copy
temp_original_list = copy.deepcopy(original_list)
这将递归地复制容器中的对象,并创建这些对象的新版本
发件人:
浅复制和深复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:
- 浅复制构造一个新的复合对象,然后(尽可能)向其中插入对原始对象的引用
- 深度副本构造一个新的复合对象,然后递归地将在原始副本中找到的对象的副本插入其中
严格地说,您的问题与词典的关系不如与它们依次保存的列表(例如
原始列表[0]['entry1']
)的关系大。在这一行:
new_dict[key] = line[key]
您在new\u dict
中引用的列表对象与在original\u list
中引用的列表对象相同。因此,当您对其进行变异时,例如:
new_dict[key].append(1)
此更改也会出现在原始词典中。因此,您也可以通过将内部列表设置为副本来解决此问题(此处只需要浅层副本,因为它包含不可变的值,而不是可变的容器):
那太好了,谢谢它解决了我的问题,我仍然不确定原始dict值是如何改变的,尽管我已经添加到我的答案中-这有帮助吗?