14

Pythonですが、プログラミングではありません。初心者はここにいます。私はリストを使ってプログラミングしていて、興味深い問題に遭遇しました。

width = 2
height = 2

# Traverse the board
def traverse(x, y):
    # The four possible directions
    squares = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
    print squares

    # Remove impossible squares
    for square in squares:
        print "now accessing", square
        if (square[0] < 1 or square[0] > width or 
            square[1] < 1 or square[1] > height or
            square == (1, height)):
            squares.remove(square)
            print "removed", square
    print(squares)

# Testing traverse
traverse(1,1)

これにより、次の出力が得られます。

[(0, 1), (2, 1), (1, 0), (1, 2)]
now accessing (0, 1)
removed (0, 1)
now accessing (1, 0)
removed (1, 0)
[(2, 1), (1, 2)]

要素(2,1)と(1,2)を完全にスキップします-それらをチェックすることさえしません!私はここで、リストをトラバースしているときにリストを変更するべきではないという答えを見つけました。そう、それは間違いなく理にかなっています。新人の間違い。しかし、なぜそれが機能しないのか誰かに教えてもらえますか?Pythonリストのベールの背後にあるものは何ですか?

4

6 に答える 6

18

他の人は、反復している配列から要素を削除すべきではないと説明しています。ただし、配列を逆方向に走査する場合は問題ありません。

この問題を解決する最もコンパクトな方法は (完了後に元の配列のコピーが必要ないと仮定して)、次のようにreversed()関数を使用することです。

for square in reversed(squares)

これは、配列の最後から反復を開始し、逆方向に動作します。この方法で要素を取り出しても、まだアクセスしていない要素の順序を変更していないため、残りのコードには影響しません。これがこれを解決する最もエレガントな方法だと思います。ここでこのトリックを学びました

于 2013-01-11T17:25:22.677 に答える
16

ステートメントfor square in squaresは、リスト内の各アイテムに順番にアクセスします。squares[0]次にsquares[1]、、、squares[2]というように、正方形がなくなるまで続きます。

削除squares[0]すると、リスト内の他のすべてのアイテムが1つ左のスロットに移動します。元のsquares[1]はになっsquares[0]ているので、forループはそれをスキップします。

于 2013-01-10T21:39:41.130 に答える
2

リストを繰り返しながら、リストから削除しています。これは良い考えではありません。
あなたが試みていることを行う他の方法があります、その1つはあなたがリストから削除したいすべてのアイテムのリストインデックスを追跡し、そしてあなたのforループの外でそれらを削除することです

于 2013-01-10T21:39:33.477 に答える
1

Pythonでリストにアクセスして要素を削除すると、リストが短くなります。簡単な例:リスト1、2、3、4、5を取り、素数> 1を削除し
ます。2番目の要素(2)を見て削除することにした場合、リストは1になります。 3,4,5ここで、3番目の要素(すでに2番目の要素を見ています)を見ると、4であることがわかります。これは素数ではないので、5番目の要素に進みます-5.削除します。
結果:1,3,4,5があります。アレイのもう一方の端から開始した場合は、問題なく動作します。わかる?

編集:私は以下に別の答えを作成しました-他のポスターは私がここで与えたよりも問題のより良い説明を与えました、しかし私はよりエレガントな解決策を持っていると思います。

于 2013-01-10T21:42:27.780 に答える
1

反復しているリストを変更しないでください!

代わりに、次のようにします。

for square in squares[:]:

元のリストを変更しながら、リストのコピーを反復処理するようにします。

于 2013-01-10T21:58:40.733 に答える