Python字典在使用中间变量时会发生更改 [英] Python dictionary changes when using intermediate variable

查看:312
本文介绍了Python字典在使用中间变量时会发生更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在给一个函数一个字符串,它通过char读取字符串char。基于正在处理的字符,JSON模板从字典中调用,稍作编辑并保存到最终字典,将被解析为JSON并保存。



问题是这个模板字典应该保持不变,但不会。不知何故,我写到中间变量的值被保存到原始模板字典中,弄乱了我要保存的后续数据。



我错过了一些基本的字典的概念?这是我第一次使用字典这样的程度,所以我甚至不会感到惊讶。



模板字典:

  self.map_legend = {#:{Id:100,Alive:False,X:0,Y:0,Width :1,Height:1,Type:Wall,PlayerNumber:0},
- :{Id:200,Alive:False,X 0,Y:0,宽度:1,高度:1,类型:盾,播放器号码:0},
x:{ID Alive:False,X:0,Y:0,宽度:1,高度:1,类型:外星人,玩家号码:0},
:{Id:400,Alive:False,X:0,Y:0,宽度:1,高度:1,类型:AlienBullet,PlayerNumber :0,
!:{Id:500,活着:False,X:0,Y:0,宽度:1,高度 Type:Missile,PlayerNumber:0},
i:{Id:500,Alive:False,X:0,Y :1,Height:1,Type:Missile,PlayerNumber:1},
M:{Id:600,Al ive:False,X:0,Y:0,宽度:3,高度:1,类型:MissileController,PlayerNumber:0},
X :{Id:700,Alive:False,X:0,Y:0,宽度:3,高度:1,类型:AlienFactory,PlayerNumber :0},
A:{Id:800,活着:False,X:0,Y:0,宽度:3,高度键入:Ship,PlayerNumber:0},
V:{Id:800,Alive:False,X:0,Y :3,Height:1,Type:Ship,PlayerNumber:1},
:{Id:900,Alive:False,X Y:0,宽度:1,高度:1,类型:空格,玩家号码:0}}

问题代码:

  for char in self.initial_game_map:
如果char!=\\\

element = self.map_legend [char]
self.id_counters [char] + = 1

元素[Id] = self.id_counters [char] + element [Id]
element [Alive] = True
元素[X] = ch ar_counter%self.state_json [Map] [Height]
元素[Y] = char_counter / self.state_json [Map] [Height]
print self.map_legend [ char]
打印元素

row.append(element)
元素= {}
char_counter + = 1

else:
self.state_json [Map] [Rows]。append(row)
row = []

一些输出:

  V 
{'宽度':3,'PlayerNumber' 1,'Y':1,'X':2,'Type':'Ship','Id':801,'Alive':True,'Height':1}
{'宽度' ,'PlayerNumber':1,'Y':1,'X':2,'Type':'Ship','Id':801,'Alive':True,'Height':1}

{'Width':1,'PlayerNumber':0,'Y':0,'X':18,'Type':'Wall','Id':103,'Alive'高度':1}
{'宽度':1,'PlayerNumber':0,'Y':0,'X':18,'类型':'墙' ':103,'Alive':True,'Height':1}

元素变量的行为与其原理一样,但您可以看到 self.map_legend 假定元素的值由于某些原因,元素已更改,这不是我想要的。发生了什么?

解决方案

元素 self.map_legend [char] 指向相同的字典,因此如果您更新元素,您将更新字典的值 self.map_legend [炭] 。你似乎想要一个这样使用的副本:

  element = self.map_legend [char] .copy()

python文档中的引用: https://docs.python.org/2/library/copy.html 。因为字典很浅,你不需要 .deepcopy()


I'm feeding a function a string, which reads the string char by char. Based on the char being worked on, a JSON template is called from a dictionary, edited slightly and saved to a final dictionary, which will be parsed to JSON and saved.

The problem is that this template dictionary should stay constant, but it doesn't. Somehow, the values I write to the intermediate variable gets saved to the original template dictionary, messing up the subsequent data I'm trying to save.

Am I missing some basic concept of the dictionary? This is my first time working with dictionaries to such an extent so I wouldn't even be surprised.

The template dictionary:

self.map_legend = {"#": {"Id": 100, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Wall", "PlayerNumber": 0},
              "-": {"Id": 200, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Shield", "PlayerNumber": 0},
              "x": {"Id": 300, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Alien", "PlayerNumber": 0},
              "|": {"Id": 400, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "AlienBullet", "PlayerNumber": 0},
              "!": {"Id": 500, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Missile", "PlayerNumber": 0},
              "i": {"Id": 500, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Missile", "PlayerNumber": 1},
              "M": {"Id": 600, "Alive": False, "X": 0, "Y": 0, "Width": 3, "Height": 1, "Type": "MissileController", "PlayerNumber": 0},
              "X": {"Id": 700, "Alive": False, "X": 0, "Y": 0, "Width": 3, "Height": 1, "Type": "AlienFactory", "PlayerNumber": 0},
              "A": {"Id": 800, "Alive": False, "X": 0, "Y": 0, "Width": 3, "Height": 1, "Type": "Ship", "PlayerNumber": 0},
              "V": {"Id": 800, "Alive": False, "X": 0, "Y": 0, "Width": 3, "Height": 1, "Type": "Ship", "PlayerNumber": 1},
              " ": {"Id": 900, "Alive": False, "X": 0, "Y": 0, "Width": 1, "Height": 1, "Type": "Space", "PlayerNumber": 0}}

The problem code:

for char in self.initial_game_map:
    if char != "\n":
        element = self.map_legend[char]
        self.id_counters[char] += 1

        element["Id"] = self.id_counters[char] + element["Id"]
        element["Alive"] = True
        element["X"] = char_counter % self.state_json["Map"]["Height"]
        element["Y"] = char_counter / self.state_json["Map"]["Height"]
        print self.map_legend[char]
        print element

        row.append(element)
        element = {}
        char_counter += 1

    else:
        self.state_json["Map"]["Rows"].append(row)
        row = []

Some output:

V
{'Width': 3, 'PlayerNumber': 1, 'Y': 1, 'X': 2, 'Type': 'Ship', 'Id': 801, 'Alive': True, 'Height': 1}
{'Width': 3, 'PlayerNumber': 1, 'Y': 1, 'X': 2, 'Type': 'Ship', 'Id': 801, 'Alive': True, 'Height': 1}
#
{'Width': 1, 'PlayerNumber': 0, 'Y': 0, 'X': 18, 'Type': 'Wall', 'Id': 103, 'Alive': True, 'Height': 1}
{'Width': 1, 'PlayerNumber': 0, 'Y': 0, 'X': 18, 'Type': 'Wall', 'Id': 103, 'Alive': True, 'Height': 1}

the element variable is behaving as its supposed to, but you can see that self.map_legend assumes the value of element for some reason after element is changed, which is NOT what I want. What's going on?

解决方案

element and self.map_legend[char] point to the same dictionary and thus if you update element you will update the values of the dictionary self.map_legend[char]. You seem to want a copy so use:

element = self.map_legend[char].copy()

Reference in the python documentation: https://docs.python.org/2/library/copy.html. As the dictionaries are shallow you don't need .deepcopy()

这篇关于Python字典在使用中间变量时会发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆