Операторы Python не выполняются последовательно?

#python #dictionary

#python #словарь

Вопрос:

У меня есть следующие три списка:

 d1 = [{"Names": ["Chris","Sam","Max"], "Color": "Blue"},{"Names": ["Albert","Robert","Julie"], "Color": "Red"}] 
d2 = [{"SomeNames": ["April","John","Erin"], "Color": "Green"},{"SomeNames": ["Phillip","Nate","Wendy"], "Color": "Yellow"}]
d3 = [{"Color": "Pink"}, {"Color": "Purple"}, {"Color": "Orange"}]
  

Если я запускаю код:

 for item in d2:
    item["Names"]=item.pop("SomeNames")
    d1.append(item)

print(d1)
  

Я получаю:

 [{'Names': ['Chris', 'Sam', 'Max'], 'Color': 'Blue'}, {'Names': ['Albert', 'Robert', 'Julie'], 'Color': 'Red'}, {'Names': ['April', 'John', 'Erin'], 'Color': 'Green'}, {'Names': ['Phillip', 'Nate', 'Wendy'], 'Color': 'Yellow'}]
  

Если я запускаю код:

 for item in d2:
    item.pop("SomeNames")
    d3.append(item)
  

Я получаю:

 [{'Color': 'Pink'}, {'Color': 'Purple'}, {'Color': 'Orange'}, {'Color': 'Green'}, {'Color': 'Yellow'}]
  

Пока все хорошо. Однако, если я попытаюсь объединить их в один и тот же цикл:

 for item in d2:

    item["Names"]=item.pop("SomeNames")
    d1.append(item)

    item.pop("Names")
    d3.append(item)

print(d1)
print(d3)
  

Я получаю:

 [{'Names': ['Chris', 'Sam', 'Max'], 'Color': 'Blue'}, {'Names': ['Albert', 'Robert', 'Julie'], 'Color': 'Red'}, {'Color': 'Green'}, {'Color': 'Yellow'}]
[{'Color': 'Pink'}, {'Color': 'Purple'}, {'Color': 'Orange'}, {'Color': 'Green'}, {'Color': 'Yellow'}]
  

Это означает, что каким-то образом, когда я выполняю обе команды сразу после друг друга, я теряю следующие элементы списка:

 {'Names': ['April', 'John', 'Erin']}
{'Names': ['Phillip', 'Nate', 'Wendy']}
  

Я ожидал получить:

 [{'Names': ['Chris', 'Sam', 'Max'], 'Color': 'Blue'}, {'Names': ['Albert', 'Robert', 'Julie'], 'Color': 'Red'}, {'Names': ['April', 'John', 'Erin'], 'Color': 'Green'}, {'Names': ['Phillip', 'Nate', 'Wendy'], 'Color': 'Yellow'}]
[{'Color': 'Pink'}, {'Color': 'Purple'}, {'Color': 'Orange'}, {'Color': 'Green'}, {'Color': 'Yellow'}]
  

Разве эти pop-команды не должны выполняться последовательно в цикле? Я не понимаю, почему это происходит?

Спасибо!

Комментарии:

1. Вы добавляете один и тот же элемент к каждому из d1 и d3. Это не копия, это тот же объект. Если вы измените его, то он будет изменен, не имеет значения, как вы к нему обращаетесь, вы увидите результаты этого изменения. — если вы также выведете d2 в конце, вы увидите, что объекты в нем выглядят точно так же, как те, которые вы добавили в d1 и d3. Вы даже можете снова получить их из d2 и снова изменить их — вы увидите эти изменения, если снова напечатаете d1 и d3.

2. Не могли бы вы предложить способ выполнить то, что я пытаюсь, в том же цикле? Как новичок, я был бы очень признателен за предложения. 🙂

3. Я предполагаю, что есть способ создать копию item . Я бы сделал это, а затем изменил и добавил это в d1, затем отдельную копию для изменения и добавления в d3. На самом деле я не использую python, поэтому я не знаю, как, — кто-то, кто действительно использует python, может прийти и ответить, или, возможно, если вы ищете, как скопировать словарь python (я думаю , что это словари — опять же: я не использую python), вы можете найти ответ.

Ответ №1:

Я думаю, что @moreON прав, если вы хотите повторно использовать dict, но изменить его в одном месте, вам нужно его клонировать или создать новый.

создайте новую версию dict:

 for item in d2:
    item["Names"] = item.pop("SomeNames")
    d1.append(item)

    d3.append({'Color': item['Color']})
  

копировать версию dict:

 for item in d2:
    item["Names"] = item.pop("SomeNames")
    d1.append(item)

    new_item = dict(item)
    new_item.pop('Names')
    d3.append(new_item)
  

Еще не придумали лучшего способа.

Ответ №2:

Вот альтернативный способ сделать это:

 for dic in d2:
    d1.append({k.replace('SomeNames', 'Names'):v for k,v in dic.items()})
    d3.append({'Color': dic['Color']})