找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 7210|回复: 10

[求助] 请教一个字典问题

3

主题

24

帖子

24

积分

贫民

积分
24
ccwybatn 发表于 2017-3-21 23:16:39 | 显示全部楼层 |阅读模式
本帖最后由 ccwybatn 于 2017-3-21 23:19 编辑
  1. <blockquote><blockquote>#原有物品
复制代码
题目是这样的,打怪得到一堆东西,然后要更新背包里的东西。
  1. #原有物品
  2. stuff={'rope':1,'torch':6,'gold coin':42,'dagger':1,'arrow':12}

  3. #列出物品清单
  4. def displayInventory(inventory):
  5.     total=0
  6.     print('物品清单:')
  7.     for v,k in inventory.items():
  8.         print(v+':'+str(k))
  9.         total+=k
  10.     print('所拥有的物品数量一共是'+str(total))

  11. #打败一头龙得到的物品清单
  12. dragonLoot=['gold coin','dagger','gold coin','ruby']

  13. #把新得到的东西加入到物品列表中
  14. def addToInventory(inventory,addedItems):
  15.     for v,k in inventory.items():
  16.         for i in addedItems:
  17.             if v==i:
  18.                 inventory[v]+=1
  19.             else:
  20.                 inventory.setdefault(i,1)
  21.     return inventory

  22. #主程序
  23. stuff=addToInventory(stuff,dragonLoot)
  24. displayInventory(stuff)
复制代码

运行后产生这样的问题
Traceback (most recent call last):
  File "E:/python/列出游戏中物品的清单.py", line 27, in <module>
    stuff=addToInventory(stuff,dragonLoot)
  File "E:/python/列出游戏中物品的清单.py", line 18, in addToInventory
    for v,k in inventory.items():
RuntimeError: dictionary changed size during iteration
现在明确的知道是第23行出了问题,可是我不明白为什么出错了,怎么改?



回复

使用道具 举报

1

主题

3

帖子

3

积分

贫民

积分
3
普箩米肖丝 发表于 2017-3-22 22:56:26 | 显示全部楼层
本帖最后由 普箩米肖丝 于 2017-3-23 12:40 编辑

我随便写写懒得测试了你可以参考一下
  1. def addToInventory(inventory, addedItems):
  2.     oriKeys = inventory.keys()
  3.     for i in addedItems.keys():
  4.         if i in oriKeys:
  5.             #直接加
  6.         else:
  7.             inventory[i] = addedItems[i]
  8. # something else
复制代码

有些地方我没写好其实还能更优雅些。。。。比如oriKeys弄成set之类的。。。
回复 支持 1 反对 0

使用道具 举报

5

主题

101

帖子

101

积分

版主

Rank: 7Rank: 7Rank: 7

积分
101

最佳新人活跃会员热心会员突出贡献

QQ
落叶秋风 发表于 2017-3-21 23:44:00 | 显示全部楼层
我机子上跑是正常的,是代码没贴全的缘故还是别的什么原因吗,楼主在测试下。
屏幕快照 2017-03-21 下午11.42.26.png
回复 支持 反对

使用道具 举报

3

主题

24

帖子

24

积分

贫民

积分
24
ccwybatn  楼主| 发表于 2017-3-22 08:28:01 | 显示全部楼层
落叶秋风 发表于 2017-3-21 23:44
我机子上跑是正常的,是代码没贴全的缘故还是别的什么原因吗,楼主在测试下。 ...

我这不行哦,你那个是python3吗?
回复 支持 反对

使用道具 举报

5

主题

101

帖子

101

积分

版主

Rank: 7Rank: 7Rank: 7

积分
101

最佳新人活跃会员热心会员突出贡献

QQ
落叶秋风 发表于 2017-3-22 11:00:42 | 显示全部楼层
ccwybatn 发表于 2017-3-22 08:28
我这不行哦,你那个是python3吗?

不是python3,是python2.7
回复 支持 反对

使用道具 举报

0

主题

7

帖子

7

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7

活跃会员热心会员突出贡献荣誉管理

Zuckerburg 发表于 2017-3-22 11:11:11 | 显示全部楼层
既要对一个字典进行display,又要随时更改这个字典,这样是行不通滴,这是我以前犯过的错:既对一个列表进行修改,又对这个列表进行遍历。你考虑一下是不是这个问题?!
回复 支持 反对

使用道具 举报

1

主题

3

帖子

3

积分

贫民

积分
3
普箩米肖丝 发表于 2017-3-22 14:15:41 | 显示全部楼层
RuntimeError: dictionary changed size during iteration
如上所述dict在迭代是改变了大小,迭代时改变被迭代的实例可不是什么好主意(只是修改值还可以)
针对你的目的我觉得应该换一种思路,更新原dict其实不用直接迭代原dict
可以先直接判断addedItems里的物品原dict有没有
如迭代addItems.keys()
回复 支持 反对

使用道具 举报

3

主题

24

帖子

24

积分

贫民

积分
24
ccwybatn  楼主| 发表于 2017-3-22 15:53:23 | 显示全部楼层
Zuckerburg 发表于 2017-3-22 11:11
既要对一个字典进行display,又要随时更改这个字典,这样是行不通滴,这是我以前犯过的错:既对一个列表进 ...

我觉得你说得这点没错,但是前面2.7可以完美运行,但是3就不行,所以我觉得应该不是这个问题。
回复 支持 反对

使用道具 举报

3

主题

24

帖子

24

积分

贫民

积分
24
ccwybatn  楼主| 发表于 2017-3-22 15:56:00 | 显示全部楼层
普箩米肖丝 发表于 2017-3-22 14:15
RuntimeError: dictionary changed size during iteration
如上所述dict在迭代是改变了大小,迭代时改变被迭 ...

如果只判断有没有的话,有的可以相加,但是没有的还是不能加进字典里啊。这个要怎么办?代码该如何写呢?只写那个addToInventory()函数部分
回复 支持 反对

使用道具 举报

3

主题

24

帖子

24

积分

贫民

积分
24
ccwybatn  楼主| 发表于 2017-3-22 16:01:18 | 显示全部楼层
Zuckerburg 发表于 2017-3-22 11:11
既要对一个字典进行display,又要随时更改这个字典,这样是行不通滴,这是我以前犯过的错:既对一个列表进 ...
  1. #原有物品
  2. stuff={'rope':1,'torch':6,'gold coin':42,'dagger':1,'arrow':12}

  3. #列出物品清单
  4. def displayInventory(inventory):
  5.     total=0
  6.     print('物品清单:')
  7.     for v,k in inventory.items():
  8.         print(v+':'+str(k))
  9.         total+=k
  10.     print('所拥有的物品数量一共是'+str(total))

  11. #打败一头龙得到的物品清单
  12. dragonLoot=['gold coin','dagger','gold coin','ruby']

  13. #把新得到的东西加入到物品列表中
  14. def addToInventory(inventory,addedItems):
  15.     for v,k in inventory.items():
  16.         for i in addedItems:
  17.             if v==i:
  18.                 inventory[v]+=1
  19.             else:
  20.                 inventory.setdefault(i,1)
  21.                 print(inventory)
  22.                 #break
  23.     return inventory

  24. #主程序
  25. stuff=addToInventory(stuff,dragonLoot)
  26. displayInventory(stuff)
复制代码

测试了一下这个代码,运行结果是这样的
{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12, 'ruby': 1}
Traceback (most recent call last):
  File "C:/Users/skyanye/Desktop/test.py", line 29, in <module>
    stuff=addToInventory(stuff,dragonLoot)
  File "C:/Users/skyanye/Desktop/test.py", line 18, in addToInventory
    for v,k in inventory.items():
RuntimeError: dictionary changed size during iteration
注意看第4行,字典其实是被修改了,但是在return的时候出错了。这个难道是因为内部出错了才导致的吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表