【问题标题】:changing value in nested dictionary python using class使用类更改嵌套字典python中的值
【发布时间】:2012-09-16 09:28:38
【问题描述】:
class warehouse:

    def __init__(self):
        self.A={}
        self.B={}   
        self.racks={'A':self.initialize(self.A),'B':self.initialize(self.B)}        

    def initialize(self,rack):
        shelf = dict([  (items,0) for items in range(1,6)  ])
        for x in range(3):
            rack[x+1]=shelf 
        return rack 

    def store(self,_id,owner_id,colour,weigth):
        import pdb;pdb.set_trace()          
        empty_position=self.empty_positions(self.store.__name__)[0]     
        self.racks[empty_position[0]][empty_position[1]][empty_position[2]]=   {'id':_id,'owner':owner_id,'colour':colour,'weigth':weigth}          
        print self.racks
    def empty_positions(self,name):

        store_list=[]
        for rack,shelfs in self.racks.iteritems():
            for shelf_number,shelf_objects in shelfs.iteritems():
                    store_list.append([rack,shelf_number])
                    for position,value in shelf_objects.iteritems():
                        if 0==value:
                            store_list.append([rack,shelf_number,position])

        return store_list

obj=warehouse()
val=obj.store(2,34,4,44)                

这是一个类仓库,我想通过调用类的 init 方法创建一个字典。现在我想使用相同的类实例将一些值存储到嵌套字典中仓库。当我调用 obj.store(2,34,4,44)。它会更新字典并给出结果。

{'A': {1: {1: {'colour': 4, 'id': 2, 'owner': 34, 'weigth': 44},
           2: 0,
           3: 0,
           4: 0,
           5: 0},
       2: {1: {'colour': 4, 'id': 2, 'owner': 34, 'weigth': 44},
           2: 0,
           3: 0,
           4: 0,
           5: 0},
       3: {1: {'colour': 4, 'id': 2, 'owner': 34, 'weigth': 44},
           2: 0,
           3: 0,
           4: 0,
           5: 0}},
'B': {1: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0},
      2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0},
      3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
     }
 }

但我期待:

{'A': {1: {1: {'colour': 4, 'id': 2, 'owner': 34, 'weigth': 44},
           2: 0,
           3: 0,
           4: 0,
           5: 0},
       2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0},
       3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}},
 'B': {1: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0},
       2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0},
       3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
      }
 }

它在键'A'和1的所有其他嵌套字典中设置值 我尝试放置 PDB 并对其进行调试,但它显示的结果相同。 但是,如果我在终端中执行此操作,那么我会得到我所期望的结果。

Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d={'A': {1: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}}, 'B': {1: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}}}
>>> d['A'][1][1]={"some_key":"some_value",}
>>> d
{'A': {1: {1: {'some_key': 'some_value'}, 2: 0, 3: 0, 4: 0, 5: 0}, 2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}}, 'B': {1: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 2: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}, 3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}}}

我不知道我可能遗漏了什么,或者有什么我无法赶上的错误。我正在使用 python 2.6.6 并尝试过这是 2.7.1。

【问题讨论】:

  • 我很难弄清楚你想做什么。

标签: python object dictionary hashmap associative-array


【解决方案1】:

当你这样做时:

shelf = dict([  (items,0) for items in range(1,6)  ])
for x in range(3):
    rack[x+1]=shelf 

您正在创建一个架子,然后将同一个架子放入架子 3 次。书架不是复制品,它们是一模一样的

您每次都需要创建一个新书架:

def initialize(self, rack):
    for x in range(3):
        rack[x+1] = dict((items,0) for items in range(1,6))
    return rack

在 python 2.7 中,使用字典推导,这可以变成:

def initialize(self, rack):
    rack.update({
        x + 1 : { item : 0 for item in range(1, 6) } for x in range(3)
    })
    return rack

【讨论】:

  • 我在上面显示了我得到的结果和我实际期望的结果,我尝试在终端上执行相同的操作。它工作正常,但不是在脚本上。脚本正在工作,你可以运行它。
  • 我展示了上面的解决方案 - 你读了吗?你在终端上做的不是同样的操作。
  • 我仍然会使用 rack[x+1] 和 dict 理解。嵌套的 dict 理解对我来说似乎很困惑
  • @gnibbler:我很难不过度使用理解。哎呀,我什至找到了一个与他们相关的python bug
【解决方案2】:

您的问题出在initialize() 方法中,特别是rack[x+1]=shelf

def initialize(self,rack):
    shelf = dict([  (items,0) for items in range(1,6)  ])
    for x in range(3):
        rack[x+1]=shelf 
    return rack 

rack[x+1]=shelf 可能看起来无害,但事实并非如此。 rack 将包含对同一个 shelf 对象的多个引用,这会产生奇怪的结果:

>>> a = {1: 2}
>>> b = [a for i in range(3)]
>>> b
[{1: 2}, {1: 2}, {1: 2}]
>>> b[0][1] = 3
>>> b
[{1: 3}, {1: 3}, {1: 3}]

请注意,当我更改一个时,对a 的单个实例的所有 引用是如何受到影响的。它们都指向同一个对象。

要解决此问题,请将 rack[x+1]=shelf 更改为 rack[x+1]=dict(shelf)。现在,您正在强制 Python 创建一个单独的 shelf 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 2022-06-13
    • 2019-01-25
    • 2021-04-14
    • 2019-12-26
    • 2019-05-21
    • 1970-01-01
    相关资源
    最近更新 更多