2011-05-01 49 views
0

我試圖將數據存儲在列表中,使得每個樣本都有與其相關的各種信息,全部列在一個列表中,然後將大量這些數據存儲在列表中。我至今是:如何讓我的列表更好地索引?

#!/usr/bin/env python 

from operator import itemgetter # For sorting 

class XaDatum (object): 

    fields = {'name':0, 'ki':1, 'amt':2, 'rep': 3, 'stage':4, 'variety':5, 
       'date':6, 'comments':7} 

    def __init__(self, name, ki, amt, rep=None, stage=None, variety=None, 
       date=None, comments = None): 
     for item in (name, rep, stage, variety, date, comments): 
      if item is not None: 
       item = str(item) 
     ki = int(ki) 
     amt = float(amt) 
     self.datum = [name, ki, amt, rep, stage, variety, date, comments] 

    def __getitem__(self, key): 
     return self.datum[self.fields[key]] 

    def copy(self): 
     return XaDatum(self['name'], self['ki'], 
          self['amt'], self['rep'], 
          self['stage'], self['variety'], 
          self['date'], self['comments']) 

    def __setitem__(self, key, item): 
     if key in ['name', 'rep', 'stage', 'variety', 'date', 'comments']: 
      item = str(item) 
     if key == 'ki': 
      item = int(item) 
     if key == 'amt': 
      item = float(item) 
     self.datum[self.fields[key]] = item 

    def __str__(self): 
     return repr(self.datum) 

    def show(self): 
     print("{0} {1} {2} {3} {4} {5} {6} {7}".format(
       self['name'], self['ki'], self['amt'], self['rep'], 
       self['stage'], self['variety'], self['date'], 
       self["comments"])) 


class XaData (object): 

    def __init__(self): 
     self.data = [] 
     self.count = 0 

    def __getitem__(self, index): 
     return self.data[index] 

    def __str__(self): 
     return repr(self.data) 

    def append(self, name, ki, amt, rep=None, stage=None, variety=None, 
       date=None, comments=None): 
     self.data.append(
      XaDatum(name, ki, amt, rep, stage, variety, date, comments)) 
     self.count += 1 

    def show(self): 
     for i in self.data: 
      i.show() 

    def copy(self): 
     returnme = XaData() 
     for item in self: 
      returnme.data.append(item.copy()) 
     return returnme 

    # Result points to the same memory! Changes to the returned 
    # znoselonglist will result in changes to the original! 
    def filter(self, inverse=False, min=-float('Inf'), max=float('Inf'), 
       ki_min=-float('Inf'), ki_max=float('Inf'), rep=None, stage=None, 
       variety=None, date=None, comment=None): 
     returnme = XaData() 
     for item in self.data: 
      match = ((item['amt'] >= min) 
        and (item['amt'] <= max) 
        and (item['ki'] >= ki_min) 
        and (item['ki'] <= ki_max) 
        and (rep is None or item['rep'] in rep) 
        and (stage is None or item['stage'] in stage) 
        and (variety is None or item['variety'] in variety) 
        and (date is None or item['date'] in date) 
        and (comment is None or item['comment'] in comment)) 
      if match^inverse: 
       returnme.data.append(item) 
     return returnme 

    def sort(self, *args): 
     if len(args) == 0: 
      args = ('name', 'ki') 
     self.data = sorted(self.data, key=itemgetter(*args)) 

    def unique(self, key): 
     key_list = [item[key] for item in self.data] 
     return sorted(list(set(key_list))) 

    def unique_kis(self): 
     kilist = [item['ki'] for item in self.data] 
     return sorted(list(set(kilist))) 

    def unique_names(self): 
     namelist = [item['name'] for item in self.data] 
     return sorted(list(set(namelist))) 


if __name__ == "__main__": 

    da = XaData() 
    da.append('x00', 35, 501, stage='B', variety='V1') 
    da.append('x01', 40, 309, stage='D', variety='V2') 
    da.append('x02', 37, 450, stage='D', variety='V1') 
    da.append('x03', 35, 470, stage='A', variety='V2') 
    da.append('x04', 40, 378, stage='B', variety='V1') 
    da.append('x05', 45, 770, stage='A', variety='V2') 

如果我跑這我可以這樣做:

In [1]: da.show() 
x00 35 501.0 None B V1 None None 
x01 40 309.0 None D V2 None None 
x02 37 450.0 None D V1 None None 
x03 35 470.0 None A V2 None None 
x04 40 378.0 None B V1 None None 
x05 45 770.0 None A V2 None None 

In [2]: daf = da.filter(variety='V1') 

In [3]: daf.show() 
x00 35 501.0 None B V1 None None 
x02 37 450.0 None D V1 None None 
x04 40 378.0 None B V1 None None 

In [4]: daf[0]['amt'] *= 0.2 

In [5]: daf.show() 
x00 35 100.2 None B V1 None None 
x02 37 450.0 None D V1 None None 
x04 40 378.0 None B V1 None None 

但我不能這樣做,

In [6]: daf[:]['amt'] *= 0.2 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 

/home/nathan/work/simo_znose/<ipython console> in <module>() 

TypeError: list indices must be integers, not str 

所以我的問題是,怎麼會我做切片工作?或者,或者,是否已經有數據類型或者已經做了我想要的東西?

在此先感謝!

彌敦道

+1

你期望'daf [:] ['amt']'返回到什麼程度?或者你預計會發生什麼結果?你想把每個'amt'值乘以'0.2'嗎? – poke 2011-05-01 21:22:37

+1

'XaDatum .__ init __()'中的'item = str(item)'行不符合您的想法。閱讀http://docs.python.org/reference/simple_stmts.html#assignment-statements。 – pillmuncher 2011-05-01 21:48:47

+0

@Poke:是的,我希望每個「amt」的值都乘以0.2 ......或者說,它會很好...... – user733664 2011-05-02 00:33:50

回答

1

你可以用與NumPy的record arrays操作表像這樣比較方便。 NumPy是Python中數組操作的事實標準。

您也可以考慮使用數據庫表,例如通過SQLite

+0

是的,我認爲numpy可能是答案。這是一個練習,看看我能用Python來走多遠。將類XaDatum放在類XaData中是我能想到的唯一方法,即允許通過諸如「多種」之類的鍵進行索引,而不是記住列號。 – user733664 2011-05-02 00:48:08

+0

@ user733664:我認爲你的純Python方法沒問題(我會用'return XaDatum(* self.datum)'實現'copy()',不過;我也會直接用正確的類型存儲所有的值的字符串,以避免轉換:)。我猜想,實質上,NumPy會做類似的事情。我喜歡NumPy的是,除了'my_arr ['variety']'之外,還可以使用更輕的'my_arr.variety'。 – EOL 2011-05-02 07:48:38

1

對我來說似乎就像切片一樣按預期工作。 daf[:]返回daf.data這是一個列表的副本 - 所以當您嘗試使用'amt'將結果編入索引時會出錯,因爲您無法使用字符串爲列表建立索引。

要重申戳的評論,目前還不清楚你想要daf[:]['amt']要做什麼。看起來好像您要更改daf副本中包含的所有的'amt'XaDatum對象。但是,那實際上是你想要的嗎?如果是這樣,爲了完整起見,您必須更改XaData.__setitem__(和XaData.__getitem__)才能接受字符串索引。

您還需要更改XaData.__getitem__,以便切片返回新的XaData對象而不是新的list對象。無論如何,您應該可以這麼做 - 無論如何,這是預期的切片行爲。

如果您要編寫自定義的__getitem____setitem__方法,您可能會發現有助於瞭解slice objects

+0

我應該補充一點,你正在做一些非常複雜的事情。你確定你不能用簡單的類來做你想做的事情,或者甚至只是一些內置的類型? – senderle 2011-05-01 22:13:16

+0

任何指針如何'__getitem__'和'__setitem__'需要改變? – user733664 2011-05-02 00:45:30

+0

回顧過去,我擔心這個問題對於我現在的回答來說過於寬泛和複雜。但是有一些注意事項:你也可以創建'__getslice__'和'__setslice__'方法,它們應該簡化切片 - 而不是字符串索引。如果你想做'* ='slice分配,你還是必須重寫'__mul__'和'__add__',並且...坦率地說,我認爲你正在用這個叫出錯誤的樹。 – senderle 2011-05-02 05:52:28

相關問題