无法解释的python dict问题

时间:2011-01-03 19:23:26

标签: python dictionary

嘿所有, 我一直试图创建一个使用字典来构造一种表格的类,但是发生了一些非常奇怪的事情..继承人我的代码

class dbase:
    def __init__(self):
        self.rows = {}
        self.cols = {}
    def addrow(self, name):
        self.rows[name] = self.cols
    def addcol(self, name):
        for x in self.rows:
            self.rows[x][name] = None
    def printit(self):
        for x in self.rows:
            print x, self.rows[x]
a = dbase()
a.addrow("coke")
a.addcol("price")
a.printit()
a.addrow("sprite")
a.printit()
好的,这是奇怪的事情。我的程序打印精灵行,因为它有一个带有“价格”值的内部字典,但在我的程序中我没有说过self.cols [“price”] =无 如此sprite的addrow函数如何将这个内部字典放入其中? 谢谢你的帮助

6 个答案:

答案 0 :(得分:4)

哇。这是我一段时间以来看到的最混乱的代码。您意识到,当您添加一行时,您只需添加与其他每列相同的字典。

def __init__(self):
    self.rows = {}
    self.cols = {}
def addrow(self, name):
    self.rows[name] = self.cols

我认为你的意思是

def addrow(self, name):
    self.rows[name] = {}

答案 1 :(得分:2)

self.rows中的每个值都已分配self.cols,因此与密钥共享相同的字典。如果您修改self.rows[x],则还会修改self.rows[y],因为它们是同一个对象。同样,如果您重新添加self.cols作为self.rows[z]的值,则它具有所有相同的内容,因为它仍然是同一个对象。

如果您想每次为该行创建一个单独的空dict,那么执行此操作:assign {}

但是你真的不需要一个课程;它只是推动你使用自定义界面来实现直接在Python中完成的东西。你可能也应该研究collections.defaultdict

答案 2 :(得分:1)

当您致电a.addcol("price")时,代码会修改self.rows[x][name],将其设置为None

因此,

self.cols设置为等于dict {'price': None}。由于每个self.rows[x]都设置为self.cols,因此每次都会打印相同的字典。

答案 3 :(得分:0)

当您设置行的列时,您总是引用self.cols - 因为Python会像引用一样处理它,无论何时更新它,您都会为指向该引用的所有内容更新它。

如果您希望每行有不同的列集,则每次都应将其初始化为适当的值。

答案 4 :(得分:0)

您一直在重复使用相同的字典实例。

def addrow(self, name):
    self.rows[name] = self.cols

请记住,Python在变量方面与Java类似 - 每个名称只是对对象实例的引用。它与C中的不同,变量赋值几乎总是意味着复制值。

如果要为行和列创建快速n-dirty表类,可以使用defaultdict,例如:

from collections import defaultdict

class RowsAndColumns:
    def __init__(self):
        self._rows = defaultdict(dict)

    def get(self, row, col):
        return self._rows[row][col]

    def set(self, row, col, value):
        self._rows[row][col] = value

matrix = RowsAndColumns()
matrix.set("Coke", "Price", 1.99)
print matrix.get("Coke", "Price") # 1.99
print matrix.get("Pepsi", "Price") # KeyError "Price"

答案 5 :(得分:0)

最简单的方法是只拥有一个词典列表。像这样:

# A new "database"
dbase = []
# Adding a new "row".
dbase.append({})
# Adding columns to a specific row:
dbase[0]['newcol'] = "The value"
# Retrieving a colum from a row which will raise a KeyError if the column doesn't exist:
dbase[0]['newcol']
# Retrieving a colum from a row which will return None if the column doesn't exist:
dbase[0].get('anothercol')

您也可以查看DefaultDict,但我认为最好先了解标准词典和对象的工作原理。