#python #dictionary
Вопрос:
У меня есть список словарей с ключом для имени и ключом для списка элементов (среди других ключей). У меня есть функция с параметрами имени и элемента. Словари проверяются на соответствие имени, и если элемент соответствует заданному набору, он становится основным элементом. В противном случае, если он соответствует другому заданному набору для разных элементов, он добавляется в список «Другие элементы».
В нынешнем виде мой код в настоящее время, похоже, добавляет эти разные элементы универсально, поскольку выходные данные всех словарей в конце содержат один и тот же список других элементов для всех перечисленных словарей. Обновление основного элемента, похоже, работает нормально, но я не могу заставить другие элементы функционировать должным образом. Ниже приведено несколько примеров.
personList = []
personStats = {"Name": "", "MainItem": "", "OtherItems": []}
Измененное имя-уникальные копии personStats добавляются в список персон, как указано выше, для каждого человека и работают по назначению.
def updatePersonItem(name, item):
itemType = verifyPersonItem(item)
if itemType == "Main":
for person in personList:
if person["Name"] == name:
person["MainItem"] = name
elif itemType == "Misc":
for person in personList:
if person["Name"] == name:
if item not in personStats["OtherItems"]:
person["OtherItems"].append(item)
Функция verifyPersonItem() сравнивает элемент с 2 различными наборами и возвращает Main или Разное. Я также написал другие итерации updatePersonItem (), которые все равно приводят к тому же результату.
Хотя мне это кажется хорошим, выполнение приведенного выше кода и печать списка лиц выводят результаты, аналогичные приведенным ниже.
{"Name": "Bob", "MainItem": "Bag", "OtherItems": ['apple', 'banana', 'mandarin', 'orange', 'pear']}
{"Name": "Alice", "MainItem": "Lunchbox", "OtherItems": ['apple', 'banana', 'mandarin', 'orange', 'pear']}
Тем не менее, я ожидаю вывода, подобного приведенному ниже, где по назначению добавляются только применимые элементы.
{"Name": "Bob", "MainItem": "Bag", "OtherItems": ['apple', 'orange', 'pear']}
{"Name": "Alice", "MainItem": "Lunchbox", "OtherItems": ['apple', 'mandarin']
Any ideas?
Edit: I have found a workaround that seems to function as intended. See below.
def updatePersonItem(name, item):
itemType = verifyPersonItem(item)
for person in personList:
if person["Name"] == name:
if itemType == "Main":
person["Main"] = item
elif itemType == "Misc":
if item not in person["OtherItems"]:
personOtherItemCopy = person["OtherItems"].copy()
personOtherItemCopy.append(item)
person["Misc"] = personOtherItemCopy
Edit2: Я добавил минимальный воспроизводимый пример моего исходного кода, чтобы смоделировать мой исходный сценарий в соответствии с просьбой. Надеюсь, это приведет к лучшему решению.
import re
personList = []
personStats = {"Name": "", "MainItem": "", "OtherItems": []}
def addPerson(name):
if not any(d["Name"] == name for d in personList):
personStatsCopy = personStats.copy()
personStatsCopy.update({"Name": name})
personList.append(personStatsCopy)
else:
updatePlayerClass(name, item)
def verifyPersonItem(item):
verifyItemPattern = re.compile(r'(Lunchbox|Bag|Bento|Apple|Orange|Mandarin|Banana|Pear)')
classMatch = re.search(verifyItemPattern, item)
boolean = bool(classMatch)
if boolean == True:
if item == "Lunchbox" or item == "Bag" or item == "Bento":
return ("Main")
else:
return ("Misc")
else:
print("Invalid item.")
def updatePersonItem(name, item):
itemType = verifyPersonItem(item)
if itemType == "Main":
for person in personList:
if person["Name"] == name:
person["MainItem"] = item
elif itemType == "Misc":
for person in personList:
if person["Name"] == name:
if item not in person["OtherItems"]:
person["OtherItems"].append(item)
addPerson("Bob")
addPerson("Alice")
updatePersonItem("Bob", "Bag")
updatePersonItem("Bob", "Apple")
updatePersonItem("Bob", "Orange")
updatePersonItem("Bob", "Mandarin")
updatePersonItem("Alice", "Mandarin")
updatePersonItem("Alice", "Lunchbox")
updatePersonItem("Alice", "Pear")
print(personList)
Комментарии:
1. сначала вы могли бы использовать
print()
для просмотра значений переменных, которые вы используете в функции.2. лучше создайте минимальный рабочий код — с примерами данных, — чтобы мы могли просто скопировать и запустить его.
3. Я не понимаю, почему у вас разные переменные
itemType
иroleType
. Иperson
иplayer
. возможно, вы проверяете значение для одногоperson
, но добавляете его к другомуplayer
. ИЛИ, может быть, вы назначили один и тот же список двум людям, поэтому, когда вы добавляете элемент в одного человека, другой человек также получает этот элемент.4. Извините, код здесь является мягкой перепиской буквального кода, я просто пропустил изменение этих переменных в новые здесь. Я нашел обходной путь, который, похоже, работает с помощью функции .copy (). Я соответствующим образом обновил сообщение.
5. новый код очень отличается — и этот код действительно показывает, что без
.copy()
него могут возникнуть проблемы.