2015-06-03 2 views
2

Я кормлю функцию строкой, которая читает строковый символ char. На основе обработанного символа шаблон JSON вызывается из словаря, слегка редактируется и сохраняется в конечном словаре, который будет обрабатываться JSON и сохранен.Словарь Python изменяется при использовании промежуточной переменной

Проблема в том, что этот словарь шаблонов должен оставаться постоянным, но это не так. Так или иначе, значения, которые я пишу промежуточной переменной, сохраняются в исходном словаре шаблонов, испорчая последующие данные, которые я пытаюсь сохранить.

Я пропустил какую-то базовую концепцию словаря? Это моя первая работа со словарями до такой степени, что я даже не удивлюсь.

Словарь шаблона:

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}} 

Код проблема:

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 = [] 

Некоторые выход:

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} 

переменная element ведет себя, как его воображаемое, но вы можете увидеть что self.map_legend принимает значение element по какой-то причине после element изменен, что НЕ то, что я хочу. Что происходит?

ответ

3

element и self.map_legend[char] указывают на тот же словарь, и, таким образом, если вы обновляете element вы будете обновлять значения словаря self.map_legend[char]. Вы, кажется, хотите копию, так что используйте:

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

Ссылка в документации Python: https://docs.python.org/2/library/copy.html. Так как словари мелкие, вам не нужно .deepcopy()

+0

Спасибо, все работает. Я подозревал, что это может быть что-то вроде этого, но не был уверен. – Yassie

+0

@Jaycee После 17 лет программирования Python это все равно иногда укусит меня. BTW следует соблюдать ту же осторожность при использовании списков. В этом случае используйте 'newlist = oldlist [:]' (пока список неглубокий). – Anthon

+0

Спасибо за подсказку :) Что именно делает список/словарь «глубоким»? – Yassie

-1

Вам необходимо, чтобы словарь, содержащийся в словаре, был изменен.

from copy import deepcopy 

element = deepcopy(self.map_legend[char]) 
Смежные вопросы