2010-04-02 20 views
4

什麼是正確的方式來形成內存表中的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'
是錯的形成表格的方式?
有沒有更好的方式來實現這些表更容易的查找?

+1

它是一個'稀疏表',還是每個單元格都包含一個值?另外,每個值都是唯一的嗎?你想快速查看基於座標的值,或者其他方式,或兩者兼而有之? – 2010-04-02 07:10:10

+0

每個單元格都會包含一個值。價值觀不一定是唯一的。我需要兩種方式來查找值。這是可以實現的嗎? – asdfg 2010-04-02 07:22:48

+0

當你尋找一個價值時你想要什麼結果?它出現的所有座標? – 2010-04-02 07:27:06

回答

7

現在我該怎樣做,如果查找 '列1' 有 '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) 

等等。一旦你的代碼工作,然後來分析,基準測試和 - 也許 - 內部優化實施的時機正確。

+0

感謝您的指導 – asdfg 2010-04-02 19:41:29

7

我想用in-memory databaseSQLite這個。從Python 2.5開始,sqlite模塊甚至在標準庫中,這意味着這甚至不會增加您的需求。

+0

如果我有成千上萬的行。 sqlite比使用列表或字典更好嗎? – asdfg 2010-04-02 08:14:24

+0

我同意Keturn,sqlite是要走的路,並且再次嘗試在python中構建表並不看pythonistic。 – gath 2010-04-02 09:00:29

+0

這比使用嵌套類型更好或更好。我使用的表格在不斷變化。是不是太多分貝寫道代價高昂?感謝答覆。 – asdfg 2010-04-02 10:16:31

0

嵌套列表應該能夠在這裏完成這項工作。如果元素在網格中分散,我只會使用嵌套字典。

grid = [] 
for row in height: 
    grid.append([]) 
    for cell in width: 
     grid[-1].append(value) 

檢查行很簡單:

def valueInRow(value, row): 
    return value in grid[row] 

檢查collumns需要一些更多的工作,因爲網格是行的列表,而不是一個collumns的列表:

def collumnIterator(collumn): 
    height = len(grid) 
    for row in xrange(height): 
    yield grid[row][collumn] 

def valueInCollumn(value, collumn): 
    return value in collumnIterator(collumn) 
+0

行不僅是整數,高度也不固定。另外,我可以迭代行字典來檢查列中的值。我只是想知道這是否可以避免迭代 – asdfg 2010-04-02 08:16:37

0

現在如何查找'column1'是否有'value11'

你問這個嗎?

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

這是你要做的嗎?

+0

是的,但我想這樣做遍歷整個表..就像'表' – asdfg 2010-04-02 11:21:10

+0

「遍歷表」中的'行'?這可能意味着什麼? – 2010-04-02 15:11:25