#python #dictionary
#python #словарь
Вопрос:
Итак, я изучаю python, используя Learn python the hard way. Я пытаюсь разработать систему инвентаризации. Цель состоит в том, чтобы встроить это в класс, который будет извлекаться классом room . Я собираюсь использовать словарь для инвентаря, чтобы при создании инвентаря для каждой комнаты я мог сказать, где они находятся в комнате.
Итак, в спальне я могу сказать, что на кровати есть нож, а не просто сказать, что вы видите нож, свечу, масло.
Прямо сейчас я работаю над тем, чтобы забрать элемент, когда кто-то говорит «возьми нож». Я могу выполнить странный поиск и установить для этого значения значение None, чтобы, когда кто-то заглядывает в комнату, оно не отображалось, но, похоже, я столкнулся с проблемой области видимости. Я прочитал несколько других вопросов на этом сайте, в которых говорилось, что, поскольку это изменяемый объект, мне не нужно выполнять глобальный dict, и когда я попытался это сделать, он получил ошибку. Я могу редактировать объект, но когда я возвращаюсь к своему оператору if и циклу for, он не будет перенесен.
Пожалуйста, помогите мне 🙂
#This is the inventory in this room
inventory = {'desk': 'Miniature Fusion Warhead',
'bed':'knife', 'sink':None}
def take(item):
if item in inventory.itervalues():
#add_item_to_inventory(item)
for key, value in inventory.iteritems():
if value == item:
print ("Wow.n"
"Look at you.n"
"Picking shit up and everything.")
value = None
else:
print ("What do you think this is?"
" The dollar store? We don't "
"got that shit here!")
# Prints out what items are in the room.
# I am hoping to later come up with an idea for how
# To make different variations of this, and have it randomly
# pick between the different ways it says what it sees.
for key, value in inventory.iteritems():
if value != None:
print "You see a %s on the %s." % (value, key)
print "What do you want to pick up?"
ui = raw_input(">")
split_ui = ui.split()
print split_ui
if len(split_ui) > 1:
if split_ui[0] == "take":
print ("You reach over to grab the %s."
"n...") % split_ui[1]
take(split_ui[1])
else:
print ("What you talking bout Willis? "
"Don't you know this is just about "
"takin shit.")
else:
print ("Who taught you how to talk?"
"n...nLet me show you how its done.n"
"Use a verb, like take, then throw in an "
"object like knife.")
print inventory
Это результат, который мне дают.
You see a knife on the bed.
You see a Miniature Fusion Warhead on the desk.
What do you want to pick up?
>take knife
['take', 'knife']
You reach over to grab the knife.
...
Wow.
Look at you.
Picking shit up and everything.
{'sink': None, 'bed': 'knife', 'desk': 'Miniature Fusion Warhead'}
Важное примечание: в настоящее время это работает, только если вы берете нож, а не боеголовку. Мне нужно найти другое решение для элементов с несколькими словами.
Спасибо!
Комментарии:
1. не могли бы вы очистить синтаксис вашего примера кода?
Ответ №1:
value
Внутри вашего цикла отличается от реального значения словаря. Это просто ссылка на это значение, поэтому, когда вы это делаете value = None
, вы фактически изменяете значение ссылки, чтобы сохранить новое значение None
, а не значение словаря.
Чтобы лучше продемонстрировать это, это перед назначением внутри for key, value in inventory.iteritems():
------- -------------------------
|value| -------> |value of the dictionary|
------- -------------------------
это после value = None
-------------------------
|value of the dictionary|
-------------------------
------- ------
|value| -------> |None|
------- ------
Как вы можете видеть, значение словаря не меняется. Изменяется только переменная value
for
цикла
. Эта переменная принадлежит области действия for
цикла, и после этого она отбрасывается.
Альтернативой было бы вместо value = None
делать:
inventory[key] = None
Комментарии:
1. Или
del inventory[key]
, и при получении из словаря, используйтеinventory.get(key, None)
. Это был бы более надежный способ сделать это.2. Большое вам спасибо за помощь! Это решило мою проблему. Я изо всех сил пытался придумать способ поиска ключа на основе значения, и я как бы объединил некоторые другие решения, и это сработало, поэтому я побежал с ним. Я никогда не думал о том факте, что на самом деле я менял не словарь, а переменную, которую я установил на значение словаря. Ваш пример действительно помог мне понять, спасибо, что научили меня, а не просто дали мне ответ!
Ответ №2:
zbs верен, вы только меняете значение указателя на значение dict . Однако вы делаете это слишком сложно:
#This is the inventory in this room
inventory = {'Miniature Fusion Warhead': 'desk',
'knife':'bed'}
player_inventory = set()
def take(item):
if item in inventory:
print("You picked up the {}".format(item))
player_inventory.add(item)
del inventory[item]
else:
print("That item doesn't exist")
while True:
print('')
print("Inventory: " ', '.join(player_inventory))
for k,v in inventory.items():
print("You see a {} on the {}".format(k, v))
print("What do you want to pick up?")
ui = raw_input("> ").split()
verb = ui[0]
item = ' '.join(ui[1:])
if verb == 'take':
if item:
print("You take the {}".format(item))
take(item)
else:
print("That item doesn't exist")
else:
print("That's not an action")