Python 内存表

6 投票
4 回答
5250 浏览
提问于 2025-04-15 21:09

在Python中,怎样才能正确地创建一个内存中的表格,以便可以直接查找行和列呢?
我想到了用字典的字典来实现,像这样,

class Table(dict):
    def __getitem__(self, key):
        if key not in self:
             self[key]={}
        return dict.__getitem__(self, key)
table = Table()
table['row1']['column1'] = 'value11'
table['row1']['column2'] = 'value12'
table['row2']['column1'] = 'value21'
table['row2']['column2'] = 'value22'
>>>table
{'row1':{'column1':'value11','column2':'value12'},'row2':{'column1':'value21','column2':'value22'}}

但是我在查找某一列的值时遇到了困难。

>>>'row1' in table
True
>>>'value11' in table['row1'].values()
True

现在,如果我想查找'column1'中是否有'value11',该怎么做呢?
这种创建表格的方法是不是错的?
有没有更好的方法来实现这样的表格,以便更容易查找?

4 个回答

0

现在我该怎么查找,如果'column1'里有'value11'呢?

你是在问这个吗?

found= False
for r in table:
    if table[r]['column1'] == 'value11'
        found= True
        break

这就是你想要做的事情吗?

7

我会使用一个内存数据库,配合SQLite来实现这个功能。SQLite模块从Python 2.5开始就已经包含在标准库里了,这意味着你不需要额外安装很多东西。

7

现在我怎么查找如果'column1'有'value11'?

any(arow['column1'] == 'value11' for arow in table.iteritems())

这种构建表格的方法错了吗?

没有,这种方法只是很“暴露”,可能有点过于直接——可以把它封装在一个类里面,这样你需要的方法就会被隐藏起来,其他部分的应用程序就不会受到实现方式的影响。

有没有更好的方法来实现这样的表格,以便更容易查找?

一旦你设计了一个你想要使用的类的接口,你可以尝试不同的实现方法,并在一个代表你使用模式的工作负载上进行测试,这样你就能找到最适合你的方法(当然,前提是表格的操作和查找占用了你应用程序运行的大部分时间——要确认这一点,可以分析你的应用程序)。

我在工作中维护的一个大型内部应用有类似但不完全相同的需求,除了行索引是整数(只有列名是字符串),列的顺序很重要,工作负载更多的是“编辑”表格(添加、删除、重新排序行或列,重命名列等)。我开始时用一个表格来实现我需要的功能,内部实现非常简单(一个字典的列表,加上一个列名的列表来保持列的顺序);现在我已经将其演变为完全不同的实现(目前基于numpy)。

我认为你应该沿着类似的思路进行:“给”你当前的实现一个漂亮的“接口”,包含你需要的所有方法,分析你的应用——除非这个表对象是性能瓶颈,否则你就完成了;如果它确实是瓶颈,你可以优化实现(实验、测量、重复;-))而不影响应用程序的其他部分。

dict继承并不是个好主意,因为你可能不想暴露dict的所有丰富功能;而且,你所做的,粗略来说,是collections.defaultdict(dict)的一个低效实现。所以,封装后者:

import collections

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 inrow(self, row, col):
        return col in self.d[row]
    def incol(self, col, val):
        return any(x[col]==val for x in self.d.iteritems())

等等——写出你应用需要的所有方法,起个有用且简短的名字,然后看看是否可以将其中一些常用的方法别名为特殊方法,比如(假设使用Python 2.*——在3.*中需要稍微不同的语法):

    def __setitem__(self, (row, col), val):
        self.add(row, col, val)

等等。一旦你的代码工作正常,然后就可以进行分析、基准测试,或许——进行内部优化。

撰写回答