2012-05-10 39 views
1

我創建了一個類MyClass,其中包含大量的仿真數據。該課程將模擬結果歸類爲具有相似結構的不同模擬。結果可以用MyClass.get(foo)方法檢索。它返回一個帶有模擬ID /數組對的字典,對於每個模擬,數組的值爲foo如何在python中創建自己的映射類型

現在我想在我的類中實現一個方法來將所有函數應用於foo的所有數組。它應該返回一個帶有simulationID/function(foo)對的字典。

對於不需要附加參數的函數,我發現了以下的解決方案非常滿意(註釋總是歡迎:-)):

def apply(self, function, variable): 
    result={} 
    for k,v in self.get(variable).items(): 
     result[k] = function(v) 
    return result 

但是,對於需要額外的參數,我們沒有看到一個功能如何以優雅的方式做到這一點。一個典型的操作將與barnp.trapz(foo, x=bar),其中兩個foobar可以MyClass.get(...)

我想在這個方向retreived x值foo整合:

def apply(self, function_call): 
    """ 
    function_call should be a string with the complete expression to evaluate 
    eg: MyClass.apply('np.trapz(QHeat, time)') 

    """ 
    result={} 
    for SID in self.simulations: 
     result[SID] = eval(function_call, locals=...) 

    return result 

的問題是,我不知道如何傳遞本地映射對象。或者我正在尋找一個錯誤的方向。預先感謝您的幫助。

Roel

+1

你的第一個例子可以簡化dpwn爲一個字典表達式:'{k:function(v)for k,v in self。獲得(可變).items()}'。 –

回答

1

我嘗試重新創建類結構(相關部分)的方式,我猜測它是建立在您身邊的(如果您可以提供簡化的代碼示例供人們玩/測試,它總是很方便)。

我想你要做的是將變量名稱轉換爲從類中獲得的變量,然後在傳入的函數中使用這些變量。除此之外,因爲每個變量實際上都是一個帶有鍵(SID)的值的字典,所以您希望結果是一個結果字典,該函數應用於每個參數。

class test: 
    def get(self, name): 
     if name == "valA": 
      return {"1":"valA1", "2":"valA2", "3":"valA3"} 
     elif name == "valB": 
      return {"1":"valB1", "2":"valB2", "3":"valB3"} 
    def apply(self, function, **kwargs): 
     arg_dict = {fun_arg: self.get(sim_args) for fun_arg, sim_args in kwargs.items()} 
     result = {} 
     for SID in arg_dict[kwargs.keys()[0]]: 
      fun_kwargs = {fun_arg: sim_dict[SID] for fun_arg, sim_dict in arg_dict.items()} 
      result[SID] = function(**fun_kwargs) 
     return result 

def joinstrings(string_a, string_b): 
    return string_a+string_b 

my_test = test() 
result = my_test.apply(joinstrings, string_a="valA", string_b="valB") 
print result 

所以適用方法獲取參數的字典,獲取每個參數的特定類的數據,並創建與那些(arg_dict)有了新的說法字典。

SID鍵是從這個arg_dict中獲得的,對於其中的每一個,計算函數結果並將其添加到結果字典中。

結果是:

{'1': 'valA1valB1', '3': 'valA3valB3', '2': 'valA2valB2'} 

的代碼可以在許多方面改變,但我認爲這將是最可讀的。當然可以加入字典,而不是使用第一個元素的SID。

+0

這確實適用於我提供的示例。 – saroele

2

有兩種方法。第一種方法是使用functools.partial

foo = self.get('foo') 
bar = self.get('bar') 
callable = functools.partial(func, foo, x=bar) 
self.apply(callable, variable) 

而第二種方法是使用由部分使用了相同的技術,你可以定義接受任意參數列表的功能:

def apply(self, function, variable, *args, **kwds): 
    result={} 
    for k,v in self.get(variable).items(): 
     result[k] = function(v, *args, **kwds) 
    return result 

注意,在這兩種情況下功能簽名保持不變。我不知道我會選擇哪一個,也許是第一個案例,但我不知道您正在處理的背景。

+0

可能存在一個誤解:您的解決方案對於那些在調用函數的名稱空間中使用已知參數的函數確實有效。例子:但是這兩種解決方案都不適用於np.trapz示例,因爲'bar'也是一個字典,每次迭代都必須選擇相應的數組。讓我們再舉一個例子:我想得到'foo'和'bar'的總和,所以結果中的鍵'SID'的值應該是'self.get(foo)[SID] + self.get( bar)[SID]' – saroele

+0

如果不同的函數具有不同的簽名,則應用的語義對我來說是錯誤的,因爲您必須爲N個不同的簽名編寫N個函數。答案不清楚,例如它是什麼'self.simulations'?它沒有出現在任何地方。寫一個數據集的例子。 –

+0

如果我的問題不是很清楚,我很抱歉。我承認我的問題有兩個部分或兩個解釋。你的答案解決了第一個問題,但不是第二個問題。 @Dirk的答案解決了這兩個問題。 – saroele

相關問題