字典值在for循环中未被更改

0 投票
2 回答
550 浏览
提问于 2025-04-18 11:14

我正在学习Python,使用的是《Learn Python the Hard Way》这本书。我想开发一个库存系统。我的目标是把这个系统做成一个类,然后让房间类来使用它。我打算用字典来管理库存,这样当我为每个房间创建库存时,就可以明确物品在房间里的位置。

比如在卧室里,我可以说床上有一把刀,而不是简单地说你看到刀、蜡烛和油。

现在我正在处理一个功能,就是当有人说“拿刀”时,能够把刀捡起来。我能做到一种奇怪的搜索,然后把这个值设为None,这样当有人查看房间时就不会显示出来,但我似乎遇到了作用域的问题。我在这个网站上看了很多其他问题,大家说因为这是一个可变对象,所以我不需要使用Global 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'}

重要提示:目前这个功能只适用于拿刀,而不适用于拿战斗头。我需要找到一个解决方案来处理多个单词的物品。

谢谢!

2 个回答

1

zbs说得对,你只是改变了指向字典值的指针的值。不过,你这样做太复杂了:

#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")
4

在你的循环里,value的值和字典里的真实值是不一样的。它其实只是指向那个值的一个引用,所以当你执行value = None时,你实际上是把这个引用的值改成了None,而不是改变字典里的值。

为了更好地说明这一点,下面是你在for key, value in inventory.iteritems():这个循环开始之前的情况:

-------            -------------------------
|value|   -------> |value of the dictionary|
-------            -------------------------

这是在执行value = None之后的情况:

                   -------------------------
                   |value of the dictionary|
                   -------------------------
-------            ------
|value|   -------> |None|
-------            ------

你可以看到,字典里的值并没有改变。只有for循环里的变量value发生了变化。这个变量只在for循环的范围内有效,循环结束后就被丢弃了。

一个替代的方法是,不用value = None,而是可以这样做:

inventory[key] = None

撰写回答