无法解释的python dict问题

无法解释的python dict问题,python,dictionary,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.r

大家好, 我一直在尝试创建一个类,它使用字典来构造一种表,但是发生了一些非常奇怪的事情。。这是我的密码

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()

好吧,奇怪的是。我的程序将sprite行打印为有一个带价格值的内部字典,但在我的程序中没有我说self.cols[price]=None的地方 那么为什么sprite的addrow函数会将这个内部字典放入其中呢? 感谢您的帮助

当您调用a.addcolprice时,代码会修改self.rows[x][name],将其设置为“无”

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

当调用a.addcolprice时,代码会修改self.rows[x][name],将其设置为无


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

哇。这是我见过的最混乱的代码。您意识到,当您添加一行时,您只是添加了与其他列相同的字典

def __init__(self):
    self.rows = {}
    self.cols = {}
def addrow(self, name):
    self.rows[name] = self.cols
我想你是说

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

哇。这是我见过的最混乱的代码。您意识到,当您添加一行时,您只是添加了与其他列相同的字典

def __init__(self):
    self.rows = {}
    self.cols = {}
def addrow(self, name):
    self.rows[name] = self.cols
我想你是说

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

当您为一行设置列时,您总是引用self.cols,因为Python将其处理为引用,所以每当您更新它时,您都会为指向该引用的所有内容更新它


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

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

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

self.rows中的每个值都被分配了self.cols,因此它们作为键共享同一个字典。如果修改self.rows[x],那么也修改self.rows[y],因为它们是同一个对象。类似地,如果随后重新添加self.cols作为self.rows[z]的值,则它具有所有相同的内容,因为它仍然是同一个对象

如果每次都想为该行生成一个单独的空dict,那么就这样做:assign{}

但是你一开始真的不需要上课;它只是促使您使用一个自定义接口来完成一些直接在Python中自然完成的事情。您可能还应该查看collections.defaultdict。

self.rows中的每个值都被分配了self.cols,因此它们作为键共享同一个字典。如果修改self.rows[x],那么也修改self.rows[y],因为它们是同一个对象。类似地,如果随后重新添加self.cols作为self.rows[z]的值,则它具有所有相同的内容,因为它仍然是同一个对象

如果每次都想为该行生成一个单独的空dict,那么就这样做:assign{}


但是你一开始真的不需要上课;它只是促使您使用一个自定义接口来完成一些直接在Python中自然完成的事情。您可能还应该查看collections.defaultdict。

您一直在重复使用同一个字典实例

def addrow(self, name):
    self.rows[name] = self.cols
请记住,Python在变量方面与Java类似——每个名称只是对对象实例的引用。它不像在C语言中,变量赋值几乎总是意味着复制值

如果要为行和列创建quick-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"

您一直在重复使用同一个字典实例

def addrow(self, name):
    self.rows[name] = self.cols
请记住,Python在变量方面与Java类似——每个名称只是对对象实例的引用。它不像在C语言中,变量赋值几乎总是意味着复制值

如果要为行和列创建quick-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"

做这件事最简单的方法就是有一个字典列表。像这样:

# 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,但我认为最好先了解标准字典和对象是如何工作的。

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

# 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,但我认为最好先了解标准字典和对象是如何工作的。

阅读所有self.rows[x]指的是同一个对象self.cols.no我在程序中的什么地方说self.cols[price]=无是的,有。这一个:self.rows[x][name]=没有一个这样说,因为self.rows[x]以前被设置为self.cols。我不知道为什么我会感到如此困惑。我认为self.cols将始终等于{}一个空dict,因为我从未明确声明self.cols={price:
None}读取所有self.rows[x]引用同一个对象self.cols.no我在程序中哪里说过self.cols[price]=None是的,有。这一个:self.rows[x][name]=没有一个这样说,因为self.rows[x]以前被设置为self.cols。我不知道为什么我会感到如此困惑。我认为self.cols总是等于{}一个空的dict,因为我从来没有显式地声明self.cols={price:None}