Python表中的KeyError

0 投票
1 回答
1532 浏览
提问于 2025-04-17 19:08

我对下面的代码有点困惑:

class Table(object):
    def __init__(self):
        self.d = collections.defaultdict(dict)
    def add(self, row, col, val):
        self.d[row][col] = val
    def get(self, row, col, default=None):
        return self.d[row].get(col, default)
    def incol(self, col, val):
        for x,y in self.d.iteritems():
            if y[col]==val:
                wholerow=y
        return wholerow.values()

在我创建了表格之后,我无法使用“incol”这个函数来获取所有的值。它总是给我一个键错误。不过,当我直接用相同的代码而不使用函数时,我就能得到我想要的结果。我的代码到底发生了什么呢……

1 个回答

0

上面的代码并不是“总是给我键错误”(这里我对“总是”这个词有异议)。比如,看看下面这段代码:

foo = Table()
foo.add("row_1", "col_1", "col_1_value")
foo.add("row_1", "col_2", "col_2_value")
print foo.get("row_1", "col_1")
print foo.incol("col_1", "col_1_value")

这段代码运行没有任何错误,并且输出了以下结果:

col_1_value
['col_2_value', 'col_1_value']

不过,如果你试着把一个不存在的列名传给 incol,你就会遇到 KeyError 错误。例如,如果你在上面的代码后面加上这一行:

print foo.incol("i do not exist", "my imaginary value")

你会看到类似下面的错误信息:

Traceback (most recent call last):
File "./stack_overflow-2013-03-14.py", line 21, in <module>
    print foo.incol("i do not exist", "my imaginary value")
File "./stack_overflow-2013-03-14.py", line 12, in incol
    if y[col]==val:
KeyError: 'i do not exist'

一个可以处理这种情况的 incol 实现示例如下:

def incol(self, col, val):
    result = None
    for x,y in self.d.iteritems():
        if col in y and y[col]==val:
            result = y.values()
            break
    return result

现在,如果你运行下面的代码:

foo = Table()
foo.add("row_1", "col_1", "col_1_value")
foo.add("row_1", "col_2", "col_2_value")
print foo.get("row_1", "col_1")
print foo.incol("col_1", "col_1_value")
print foo.incol("i do not exist", "my imaginary value")
print foo.incol("i do not exist", None)

你会得到:

col_1_value
['col_2_value', 'col_1_value']
None
None

你也可以使用 Martijn Pieters 提出的以下 incol 实现:

def incol(self, col, val):
    result = None
    for x,y in self.d.iteritems():
        if y.get(col)==val:
            result = y.values()
            break
    return result

但在这种情况下,如果你传入一个不存在的 col 名称,并且 val=None,那么它会匹配任何行。相应的输出将是:

col_1_value
['col_2_value', 'col_1_value']
None
['col_2_value', 'col_1_value']

也许这就是你想要的应用行为。最终的决定权在你。

撰写回答