2012-03-29 8 views
2

私はPythonのイテレータには新しく、多分私の言語が正しいとは限りません。イテレータの書き込みアクセス?またはnumpyのジェネレータに値を送る配列

Iはnumpy.ndarrayのリストをラップするクラスを有する:

class wrapper: 
    def __init__(self, myList): 
     self.myList = myList 

    def getArrayIterator(self): 
     for arr in self.myList: 
      yield arr 

#set list of arrays in wrapper 
myList = [rand(3,3), rand(3,3), rand(3,3)] 
w = wrapper(myList) 

私はそれを理解できるように、第二の方法は、発電機を返します。 は今、私はリストをループにその発電機を使用し、何か他に配列をリセットしたい:

for a in w.getArrayIterator(): 
    a = zeros((3,4)) 

私はここに参照セマンティクスでパスを持つように期待していたが、それはケースのようには思えません。

だから私は、Pythonのsend()getArrayIterator機能でを使用してみました:

# ... 
def getArrayIterator(self): 
    for arr in self.myList: 
     val = (yield arr) 
     if val is not None: 
      arr = val 
# ... 

しかし、その文句を言わない作業のいずれかのために:

a.send(zeros((3,4))) 
    AttributeError: 'numpy.ndarray' object has no attribute 'send' 

が私の目的の動作を達成するために簡単な解決策はありますか? 何か不足していますか?


EDIT:私が私の実際の問題に関する詳細な情報を提供しなければならないことを、私に指摘されています。上記の例はもちろん簡略化されています。

私はテンソルTをクラスとしてカプセル化したnumpy.ndarrayというリストのリストを持っています。 T:t_ijklの要素にアクセスするときは、リストに格納された行列を掛ける必要があります。A(i)*B(j)*C(k)*D(l)、最初と最後は行/列ベクトルです。

したがって、それぞれのアプリケーションのグリッドポイントに属するA、Bのセットなどがあります。

これで、各グリッドポイントに関連付けられている行列に対するすべてのグリッドポイントとイテレータに対してイテレータを使用したいと考えました。

最初のアイデアは、イテレータのC++スタイルを使用して行列を読み書きすることでした。しかし、agfが下で指摘したように、これは実際に実現可能なアプローチではありません。そこで私は、読み込みアクセスと、特殊なセッターメソッドのためだけに、異なるイテレーターを使用して行列の新しい値を設定することにします。

+0

あなたがしようとしていることが良い方法であるかどうかはわかりません。おそらく、あなたが必要とするものを達成するためのよりよい方法があります。あなたの入力配列と望ましい出力の例を教えてください。 –

+0

私はどちらか分かりません。D クラス全体が、テンソルの分解スキームの一種である行列積状態を表します。テンソルの各要素は、関連する行列の積として表されます。例えば、テンソル3の場合、element_ijkにアクセスしたいのですが、実際にt_ijk = A(i)* A(j)* A(k)を実行します。各インデックスi、j、k ...は格子上の物理的インデックスに属し、A行列はnp.ndarrayのリストのリストに格納される。実際には2つのことが必要なのです... –

+0

...まず、個々の物理グリッドポイント上の行列のセットを繰り返していきたいと思います。そして、第二に、特定のサイトの個々のマトリックスを個別に繰り返していきたいと思います。 –

答えて

2

私はこれが単純な例であると仮定しています。あなたが持っているクラスでは、通常のリストを使用しない理由がないようです。あなたは

name = somelist[0] 
name = 'other' 

を行うと

あなたは、オブジェクト'other'で名前nameを指し、somelistの最初のインデックスにあるオブジェクトの名前nameを指しています。 somelist[0]'other'に指摘することはありません。

のでsendに加えて、あなたが実際にリストに割り当てる必要があります。

class wrapper: 
    def __init__(self, myList): 
     self.myList = myList 

    def getArrayIterator(self): 
     for i, arr in enumerate(self.myList): 
      yarr = (yield arr) 
      if yarr is not None: 
       self.myList[i] = yarr 

#set list of arrays in wrapper 
myList = [1, 2, 3, 4, 5] 
w = wrapper(myList) 
witer = w.getArrayIterator() 
try: 
    a = next(witer) 
    for i in range(6, 11): 
     print a, 
     a = witer.send(i) 
except StopIteration: 
    pass 
print 
print w.myList 
+0

ありがとうございましたありがとうございましたallotough: 私はforループ内の既に参照されていないIteratorにアクセスしたため、ループを明示的に書き留めているため、AttributeErrorのように思えます。 これを行うためのより良い方法はありますか?全体のtry catch構造体は、イテレータを使用して私の目的を破っています。ループやインデックスの代わりにクリーンなコードを使用します。 –

+0

@MischaObrecht 'send'の仕組みのために' try'/'except'ブロックを使わなければならないと思います。なぜあなたは単にリストを使わないだけではないのかまだ解明されていません - 指標でアクセスする必要はありません。私はあなたが物事を複雑にしている理由、またはあなたが反復しているアイテムを置き換える必要がある理由を理解していません。 – agf

+0

ああ、はい、それは単純化された例です。あなたが興味を持っているなら、上の最初の質問に対する私の解説。 Thx 私はリストを使用すると、コードは遅かれ早かれリスト[site_index] [first_physicalIndex] [secondPhysicalIndex] [rowIdx、colIdx]のようなインデックスの恐ろしい混乱になります... –

-1

あなただけ多分あなたがしたいよう

+0

私は__send )__機構は動作しませんでした。 (私はちょうど私のポストの前半で、みんなが私がしたいことのアイデアを得ることを確かめたかった。) –

+1

これはPy2.5以降は当てはまりませんでした:http://docs.python.org/whatsnew/2.5.html#pep-342-new-generator-features – lvc

0

が鳴り、それを記述しない発電機(yieldキーワード)を使用して値を読み取ることができます__getitem____setitem__を実装します。

class wrapper: 
    def __init__(self, myList): 
     self.myList = myList  

    def __iter__(self): 
     for arr in self.myList: 
      yield arr  

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

    def __setitem__(self, key, value): 
     self.myList[key] = value 

使用法:

for index, arr in enumerate(w): 
    same_arr = w[index] 
    w[index] = zeros((3,4)) 

あなたはそれがあなたの人生を容易になると思う場合は、実装することができ、他の便利な機能がたくさんあります。エミュレートするコンテナの種類についてはdocumentationです。

+0

これは 'send'とちょうど動作については説明しませんあなたがユーザー定義クラスではなく 'list'を使用していたように、正確に_ – agf

+0

@agf質問の私の理解は、ラッパークラスの目的は、numpy配列への呼び出しを傍受して、単にジェネレータについて学ぶのではなく、何かをすることでした。私は、ジェネレータと一緒に遊んでみたいと思っているなら、クラスは必要ないと思っていました。 – Dunes

+0

することができます。私は彼の理由で推測しなかったが、それは理にかなっている。 – agf

関連する問題