Python dict的值在我将其传递给函数时会发生变化,而它们不应该';T

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_

最近学习python时,我有一个程序,它获取一个dict列表(列表中的每个dict都有其他dict的重复键)

然后它将其传递给一个函数,该函数的任务是聚合值中的数据并返回一个dict,但是,当我在函数调用后再次访问原始dict时,它已使用单个dict中的值进行了更新,我看不到正在执行该操作的方法中的任何代码部分,已经被困了几个小时了

这是我的密码:

#!/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值是如何改变的,尽管我已经添加到我的答案中-这有帮助吗?