2011-03-28 66 views
0

我仍然在python中挖掘,並且有一些事情是我的C++背景獲得的。例如,我有一個類python:迭代使用類方法

class crack(object): 

    def __init__(self, sz1,sz2): 
     self.z1 = sz1 
     self.z2 = sz2 

    def smallz_Z(self,z,z1,z2): 
     return z - 0.5*(z2-z1) 

    def get_pot(self,z): 
     Z = smallz_Z(z,self.z1,self.z2) 

     try: 
      result = np.sum(np.arange(self.n) * self.coeffs * (1.0/(cmath.sqrt(Z - 1.0) * cmath.sqrt(Z + 1.0))) 
         * ((Z - cmath.sqrt(Z - 1.0) * cmath.sqrt(Z + 1.0)) ** np.arange(self.n))) * (2.0/(self.z2 - self.z1)) 

我要創造裂紋元素的列表,

crack_list = [] 
crack_list.append(crack(z1,z2)) ... 

現在我需要使用一個迭代器來獲取潛在的所有值, matplotlib輪廓函數的例子。我不能做這樣的事情:

result = np.sum(crack_list.get_potential(z)) 

現在我正在做的「傳統」的方式:

def potential_value(z, crack_list): 
    potential = complex(0, 0) 

    for element in crack_list: 
    potential = potential + element.get_potential(z) 

    return potential 

,如果我用一個for循環,它說,該元素裂紋不可迭代。比方說,我試着

x = np.linspace(self.x1, self.x2, self.step) 
    y = np.linspace(self.y1, self.y2, self.step) 
    X, Y = np.meshgrid(x, y) 
    Z = X +1j*Y 

    F = np.vectorize(potential_value) 

但在這裏我有一個問題:

F(Z, crack_list) 

    for element in crack_list: 
     TypeError: 'crack' object is not iterable 

我怎麼能這樣做?謝謝。

編輯:謝謝你的答案。我仍然知道列表的理解,所以它仍然擊敗我。比方說,我想改變我的列表理解的實施,使我改變功能

def potential_value(z_list, crack_list, u_flow): 

return [np.sum([c.get_potential(z) for c in crack_list]) + u_flow.get_potential_no_c(z) for z in z_list] 

當我試圖在同一時間,現在用兩個列表解析,所以潛力將返回一個數組所有z_list變量的所有結果 - 注意z_list應該是複雜類型的列表。有沒有辦法做到這一點只爲z_list中的一個複雜的值,沒有不得不通過一個列表只有一個值?或者我必須做某種測試?

+0

等等!你似乎試圖遍歷一個破解對象列表,而不是一個單一的破解。在我看來,crack_list不包含列表對象,而是包含一個列表對象。你能證實嗎? – batbrat 2011-03-28 14:55:45

回答

1

除了get_pot()方法不返回任何東西,它看起來像你沒有在任何地方定義self.nself.coeffs。我打賭coeffs的意思是一個numpy向量,並且它的長度是n,我假設它們可以在Crack之間變化,如z1z2

基於這些假設,我調整你的類一點:

class Crack(object): # convention is to use capitalized class names 

    def __init__(self, z1, z2, coeffs): 
     self.z1 = z1 
     self.z2 = z2 
     self.coeffs = np.array(coeffs) 
     self.n = len(coeffs) 

    def __repr__(self): 
     return "Crack(z1=%s, z2=%s, coeffs=%s)" % (self.z1, 
                self.z2, 
                self.coeffs) 
    def get_big_Z(self, little_z): 
     # this may not need to be its own function, unless you 
     # use it separately from get_potential() 
     return little_z - 0.5 * (self.z2 - self.z1) 

    def get_potential(self, z): 
     Z = self.get_big_Z(z) 
     return (np.sum(np.arange(self.n) * self.coeffs * 
         (1.0/(np.sqrt(Z - 1.0) * np.sqrt(Z + 1.0))) * 
         ((Z - np.sqrt(Z - 1.0) * np.sqrt(Z + 1.0)) ** 
         np.arange(self.n))) * 
       (2.0/(self.z2 - self.z1)) 
       ) 

現在,假設你有(或能夠產生)的z1z2coeffs值的列表每個Crack

>>> # dummy information, this makes three Crack objects 
... 
>>> z1_values = [3.0, 1.1, 0.2] 
>>> z2_values = [0.01, 0.02, 0.03] 
>>> coeff_values = [[1.1,1.0], 
...     [2.2,2.0], 
...     [3.3,3.0]] 

當對象被實例化時,coeff列表被轉換爲ndarray

您可以crack_list與內置函數map()這樣的:

>>> crack_list = map(Crack, z1_values, z2_values, coeff_values) 
>>> from pprint import pprint 
>>> pprint(crack_list) 
[Crack(z1=3.0, z2=0.01, coeffs=[ 1.1 1. ]), 
Crack(z1=1.1, z2=0.02, coeffs=[ 2.2 2. ]), 
Crack(z1=0.2, z2=0.03, coeffs=[ 3.3 3. ])] 

然後你就可以計算出總的潛在一段z值,說z = 5.0z = 3.14,如:

>>> def total_potential(z, cracks): 
...  return sum(c.get_potential(z) for c in cracks) 
... 
>>> 
>>> print total_potential(5.0, crack_list) 
-0.772861759407 
>>> print total_potential(3.14, crack_list) 
-1.99073949493 

瞧。作爲一個支票,我也會做一些筆和紙的計算,以確保大方程正在做它應該做的事情。

5

要迭代的對象需要有__iter__()方法,該方法返回一個迭代器(或序列)。迭代器應該實現方法next(),這將產生元素或raise StopIteration是沒有更多的元素。就如此容易。

+0

如果__iter__返回迭代器以外的任何東西,比如非迭代器序列,則iter()將引發TypeError。 – 2014-11-20 23:53:38

1

首先,我沒有看到你的get_pot方法返回任何東西。它應該以return result結尾,我想。

其次,權宜之計將遍歷你的對象的列表:

[e.get_pot(i) for i in range(10)] 

但最好的,因爲你正在使用numpy的,你應該把你的班級接受陣列(它看起來像它可能已經)。查看將sz1,sz2z作爲等形二維數組輸入時會發生什麼情況。如果你總結了一個軸,get_pot應該返回一個可迭代的數組。這將避免創建實例列表並利用numpy提供的加速。(該解決方案的有效性是有點依賴於裂紋實例的數量必須與您共創的頻率和破壞新的實例)

1

您可以創建一個列表理解潛力的列表,免去

result = np.sum(crack_list.get_potential(z)) 

result = np.sum([elem.get_potential(z) for elem in crack_list]) 

Map和Reduce也可以在這種情況下使用。