2

Python で for ループを複製する際に問題が発生しています。

これは、for ループの側面だけを含む私の C スタイルのスクリプトです。

for ($c=0 ; $c<size($verts); $c++)
{ 
//// do some code here 
$verts = remove($verts[c],$verts); /// remove this item from the $verts list
$c-=1; /// lower the index becuase an item was removed
     for ($n=0 ; $n<size($verts); $n++) 
         {
         if($condition)
         $verts = remove($verts[$n],$verts); /// remove this item from the $verts list
         $n-=1;  /// lower the index becuase an item was removed
         }        
}         

Python では、インデックスを減算することはできないようです:

item = range(10); 
for i in item :
del item[i]
i-=1 # this doesn't do anything for the next interation

上記の c ループを Python で記述する最良の方法は何ですか?

編集:これは、Pythonで必要なときに機能するループです

count = range(len(vtx)) 
for num in count: 
if len(vtx) != 0:    
    p.append ([]); p[len(p)-1].append(vtx[0])
    v.append ([]); v[len(p)-1].append(vec[0])    
    a = vec[0] 
    del vtx[0]    
    del vec[0]
    count2 = range(len(vtx))
    n2  = 0;
    for num2 in count2:
        b = vec[n2]
        distance = math.sqrt((a[0] - b[0])**2 + (a[1]- b[1])**2 + (a[2]- b[2])**2);
        if distance <= threshold  : 
            p[len(p)-1].append (vtx[n2])
            v[len(p)-1].append (vec[n2])
            vtx.remove(vtx[n2])  
            vec.remove(vec[n2])
        else:
            n2+=1 
4

4 に答える 4

3

編集: 投稿されたアルゴリズムに基づいて、少しクリーンアップ

p, v = [[vtx.pop(0)]],[[vec.pop(0)]]
while len( vtx ):       
   x = vtx.pop( 0 )
   b = vec.pop( 0 )
   a = v[ -1 ][ 0 ]       
   if threshold >= math.sqrt((a[0] - b[0])**2 + (a[1]- b[1])**2 + (a[2]- b[2])**2):
      v[ -1 ].append( b )
      p[ -1 ].append( x )
   else:
      v.append( [ b ] )
      p.append( [ x ] )

よくわかりません

元の PHP コードが機能するかどうかもわかりません。あるいは、そうかもしれませんが、偶然であり、確実に効率的ではありません。リストを反復処理して、特定の値に一致するアイテムを削除するとします。これを行う際の重要な問題の 1 つは、反復しようとしているリストそのものを変更していることに気付いたようです。これは Python では非常に簡単です。

for c in verts[:]:
    if remove_condition(c): 
        verts.remove(c)

ここでは、頂点リストのコピーを作成して、[:] で反復処理します。各反復では c を使用します。これは、頂点 -copy- 内の項目への参照です。次に、値 c を指定して元のリストで remove() を呼び出します。これにより、検出された値 c の最初のインスタンスが削除されます。

明らかに、辞書などを含むさまざまな状況でここには多くのニュアンスがありますが、これで始めることができます.

Python チュートリアルは通常、優れたリソースですhttp://docs.python.org/2/reference/compound_stmts.html#for

于 2013-03-16T15:37:35.693 に答える
3

これを実装する 1 つの慣用的な方法は次のとおりです。

items = [el for el in items if <condition>]

whereは、保持<condition>する要素に対して true と評価されます。

たとえば、0 から 9 までの偶数を取得するには、次のようにします。

items = list(range(10))
items = [el for el in items if el % 2 == 0]

現在のコードの主な問題は、for i in itemインデックスを反復処理するのではなく、要素自体を反復処理することです。インデックスを使用することは可能ですが、かなり非 Pythonic コードになる傾向があります。さらに、リストを反復しながらリストを変更することに関連する複雑さがあります。

于 2013-03-16T15:24:45.990 に答える
1

iあなたはそれがあなたのコードのインデックスだと思っているようです。そうではありません。iリストの値です。インデックスの範囲を反復するには、 を使用しますfor i in range(len(item)):

ただし、リストからアイテムを削除するより良い方法は、手動でインデックスを反復して を使用するよりも、リスト内包表記を使用することdelです。リスト内包表記は、新しいリストを変更するのではなく、新しいリストを作成しますが、ユース ケースに適用できることを願っています。

于 2013-03-16T15:25:53.963 に答える
1

反復処理中にリストからアイテムを削除するのは非常に難しい場合があります。最も安全な (エラーが発生しにくい) 方法は、必要な要素のみを含むリストのコピーを作成するか、不要な要素を後で削除することです。

例:

for ループを使用して、 に偶数のみの新しい配列を作成しますitems。これは、リスト内包表記を書くよりも長くなりますが、Python に慣れていない人にとってはおそらくより読みやすいでしょう:

items = range(10)
new_items = []
for item in items:
    if item % 2 == 0:
        new_items.append(item)
items = new_items
print items

出力:

[0, 2, 4, 6, 8]

リスト内包表記を使用すると、次のように記述できます。

items = range(10)
items = [item for item in items if item % 2 == 0]

余談ですが、組み込み関数enumerateは、C コードから移行するときに役立ちます。for ループは次のように記述できます。

items = ['foo', 'bar', 'spam', 'eggs']
for i, item in enumerate(items):
    print i, item

出力:

0 foo
1 bar
2 spam
3 eggs
于 2013-03-16T15:51:15.513 に答える