1
a = [0,1,2,3,4,5]
for b in a:
  print ":"+str(b)
  a.pop(0)

これがリスト全体とそのすべての項目を順番に処理すると考えて、このコードを実行し、これを期待しました。

:0
0
:1
1
:2
2
:3
3
:4
4
:5
5

代わりに私はこれを得ました:

:0
0
:2
1
:4
2

なぜこれが起こったのか理解できましたが、これはpythonのエラーですか?現在のリストの長さではなく、元のオブジェクトをすべて通過するべきではありませんか? そして、なぜこれは範囲外のエラーをスローしなかったのですか? IE: まだやるべきではなかった:

:0
0
:1
2
:2
4
:3
Error
:4
Error
:5
Error
4

4 に答える 4

5

これは完全に「予期される」動作であり、文書化されています。リストを反復処理するときは、基本的にメモリの場所を反復処理しています。リストから何かをポップすると、リスト内のそれ以降のすべてが 1 インデックス分リストの先頭に近づきます。したがって、アイテムをスキップすることになります。リストの最後に到達すると、反復が停止します。

通常、このようなことを行うときは、リストのコピーを反復処理する必要があります。

for b in a[:]:
    ...

コメントに示されているように、リストを逆の順序で反復すると、次のようになります。

for b in reversed(a):
    a.pop()

これは意図したとおりに機能します。これは、最終要素を常に引き離しているため、まだ見ていない要素のリスト内の位置をシフトしていないためです。

于 2013-01-22T18:37:10.027 に答える
4

リストをループし、同時に変更しています。を使用.pop()するとリストが短縮されますが、反復子ポインターは更新されません。

代わりにコピーを使用してください:

for b in list(a):

また

for b in a[:]:

スライス表記は[:]リストのコピーを返します。

別のアプローチは、while代わりにループを使用することです。

while a:
    print a.pop(0)

空のリストは boolean としてテストされるためFalseです。

Pythonforループはその引数を反復子として使用し、それ自体はインデックスを保持しません。for要素を削除したことをループが「認識する」方法はありません。代わりに、list()そのポインターを保持するのは反復子です。

>>> a = [0,1,2,3,4,5]
>>> itera = iter(a)
>>> itera.next()  # index 0 -> a[0] is 0
0
>>> a.pop(0)
0
>>> a
[1,2,3,4,5]
>>> itera.next()  # index 1 -> a[1] is 2
2

その反復子はカウンターを保持し、反復子を呼び出すたびに、カウンターがリストの現在の長さと等しくなるまで、その値が何であれnext()、次のインデックスで値を提供します。

于 2013-01-22T18:36:57.097 に答える
0

ループの各反復でfor、条件をチェックする必要がありb in aます。

a = [0,1,2,3,4,5]
for b in a:
  print ":"+str(b)
  a.pop(0)

b = 0およびin a(a 内の要素を意味する) は5です。次に、文字列化されたバージョンを出力しa[b]てから、配列の最初の要素を削除します。したがって、反復 2 は次のようになります。

a = [1, 2, 3, 4, 5]
b = 1 (it incremented)
size of a = 4 (it shrank)

次に、それらは になりb=2、 a のサイズは 3 になります。予期していた範囲外エラーを生成する最後の反復bは、配列のサイズよりも大きくなるため、発生しません。これで完了です。

于 2013-01-22T18:56:03.663 に答える
0

.pop()ループで使用する場合、一般的なイディオムは次のように使用することwhileです。

a = [0,1,2,3,4,5]
while a:
  print ":{}".format(a.pop(0))

または、そこにある印刷されたパターンが必要な場合:

a = [0,1,2,3,4,5]
while a:
    print ":{}\n{}".format(a[0],a.pop(0))

版画

:0
0
:1
1
:2
2
:3
3
:4
4
:5
5
于 2013-01-22T18:42:34.350 に答える