Python 内存表
在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 个回答
现在我该怎么查找,如果'column1'里有'value11'呢?
你是在问这个吗?
found= False
for r in table:
if table[r]['column1'] == 'value11'
found= True
break
这就是你想要做的事情吗?
现在我怎么查找如果'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)
等等。一旦你的代码工作正常,然后就可以进行分析、基准测试,或许——进行内部优化。