2015-04-14 49 views
1

我正在尋找一個python中的SQL關係表類數據結構,或者一些提示(如果沒有一個存在的話)。從概念上講,數據結構是一組對象(任何對象),支持高效查找/過濾(可能使用類似於SQL的索引)。python中的關係數據結構

例如,可以說我的對象全都具有屬性ABC,我需要過濾它們,因此我定義的數據應該由它們索引。這些對象可能包含許多其他成員,這些成員不用於過濾。數據結構應支持相當於SELECT <obj> from <DATASTRUCTURE> where A=100的操作(對於BC也是如此)。也應該可以通過多個字段進行篩選(where A=100 and B='bar')。

的要求是:

  1. 應該支持大量項目(〜200K)的。這些項目必須是對象本身,而不是它們的一些扁平版本(它排除了sqlite和可能的pandas)。
  2. 插入要快,應避免的存儲器再分配(這幾乎排除了pandas
  3. 應該支持簡單的過濾(如上面的例子),其必須比O(len(DATA))更有效率,即,避免「全表掃描」 。

這樣的數據結構是否存在?


請不要使用sqlite。我需要重複轉換object-> row和row-> object,這很費時間和麻煩,因爲我的對象不一定是平坦的。

此外,請不要建議使用熊貓,因爲重複插入的行太慢,因爲它可能需要頻繁的重新分配。

回答

1

只要您在(a,b,c)上沒有任何重複項,您可以輸入由元組(a,b,c)索引的對象,並定義過濾器方法(可能是一個生成器)返回符合條件的所有條目。

class mydict(dict): 
    def filter(self,a=None, b=None, c=None): 
     for key,obj in enumerate(self): 
      if (a and (key[0] == a)) or not a: 
       if (b and (key[1] == b)) or not b: 
        if (c and (key[2] == c)) or not c: 
         yield obj 

這是一個醜陋和非常低效的例子,但你明白了。我相信itertools中有更好的實現方法,或者其他的東西。

編輯:

我一直在想這件事。昨晚我玩弄了一些東西,想出了將這些對象存儲在一個列表中,並通過所需的關鍵字段存儲索引的字典。通過獲取所有指定條件的索引的交集來檢索對象。像這樣:

objs = [] 
aindex = {} 
bindex = {} 
cindex = {} 

def insertobj(a,b,c,obj): 
    idx = len(objs) 
    objs.append(obj) 
    if a in aindex: 
     aindex[a].append(idx) 
    else: 
     aindex[a] = [idx] 

    if b in bindex: 
     bindex[b].append(idx) 
    else: 
     bindex[b] = [idx] 

    if c in cindex: 
     cindex[c].append(idx) 
    else : 
     cindex[c] = [idx] 

def filterobjs(a=None,b=None,c=None): 
    if a : aset = set(aindex[a]) 
    if b : bset = set(bindex[b]) 
    if c : cset = set(cindex[c]) 
    result = set(range(len(objs))) 
    if a and aset : result = result.intersection(aset) 
    if b and bset : result = result.intersection(bset) 
    if c and cset : result = result.intersection(cset) 
    for idx in result: 
     yield objs[idx] 

class testobj(object): 
    def __init__(self,a,b,c): 
     self.a = a 
     self.b = b 
     self.c = c 

    def show(self): 
     print ('a=%i\tb=%i\tc=%s'%(self.a,self.b,self.c)) 

if __name__ == '__main__': 
    for a in range(20): 
     for b in range(5): 
      for c in ['one','two','three','four']: 
       insertobj(a,b,c,testobj(a,b,c)) 

    for obj in filterobjs(a=5): 
     obj.show() 
    print() 
    for obj in filterobjs(b=3): 
     obj.show() 
    print() 
    for obj in filterobjs(a=8,c='one'): 
     obj.show() 

它應該是相當快的,儘管對象在列表中,它們可以直接通過索引訪問。 「搜索」是在哈希字典上完成的。

+0

@Martijn彼得斯給出了一個很好的例子,這個問題的匹配/選擇/過濾方面使用fnmatch在這裏的問題[鏈接](http://stackoverflow.com/questions/29638382/how-to-retrieve-dicts -a-list-of-dicts-using-wildcard-key-value)。 –

+0

我喜歡這種方法 – shx2