1

次のpythonコードがあります:

x = range(0,10)
print x

for number in x: 
    print(number)
    if number%2<> 0: 
        x.remove(number)

print x

奇妙なことに、出力は次のとおりです。

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
3
5
7
9
[0, 2, 4, 6, 8]

最初と最後の行は正しいのに、なぜ 2、4、6、8 が出力されないのですか? print ステートメントが if ステートメント内にありません。

Windows 7でpython(x、y)を使用しています。また、Pythonは初めてです... C++に慣れています

4

6 に答える 6

2

リストはそのインデックスを使用して反復されますが、要素を削除するといくつかのインデックスがスキップされます。

例えば:

[0,1,2,...] # (iterator is at second - print 1)

削除する

[0,2,3,...] # (iterator is still at second)

イテレータの進行

[0,2,3,...] # (iterator is at third - print 3)
于 2013-04-14T22:24:24.530 に答える
2

printわかりやすくするためにいくつかのステートメントを追加します。

x = range(10)

for index, number in enumerate(x):
    print "x is      ", x
    print "element is", number
    print "index is  ", index
    print

    if number % 2 == 0: 
        x.remove(number)

そして出力:

x is       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
element is 0
index is   0

x is       [1, 2, 3, 4, 5, 6, 7, 8, 9]
element is 2
index is   1

x is       [1, 3, 4, 5, 6, 7, 8, 9]
element is 4
index is   2

x is       [1, 3, 5, 6, 7, 8, 9]
element is 6
index is   3

x is       [1, 3, 5, 7, 8, 9]
element is 8
index is   4

ご覧のとおり、リストから要素を削除しても、 は だけindex上昇し続けます。1これが、ループが要素をスキップする原因です。

他の人が指摘しているように、リストをループして要素を削除することはお勧めできません。代わりにコピーをループします。

for number in x[:]:

または:

for number in list(x):

さらに良いことに、リスト内包表記を使用して新しいリストを作成します。

[number for number in x if number % 2 == 0]
于 2013-04-14T22:29:26.333 に答える
1

基本的に、同時に削除しながら何かを繰り返すと、奇妙な動作が発生する可能性があります。何が起こっているかというと、すでに繰り返し処理したインデックスにシフトされているために、いくつかの値をスキップしているということです。

必要なことを行う(いくつかの項目を除外する)より良い方法は、リスト内包表記を使用することです。たとえば、次のようになります。

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

このrangeステップを使用して偶数のみを作成することもできますが、上記のソリューションを使用すると、任意の条件で除外できます。

一部の数値が出力されない理由は、値をループして削除している間に値の位置が変化するためです。を削除すると1、すべての値が 1 つの位置だけシフトされることを想像できます。イテレータは以前は があった場所を指していますが2、現在は値が である3ため、2は印刷されません。そして、これは残りの値についても続きます。

于 2013-04-14T22:23:10.750 に答える
1

Mark Rushakoff が言及しているように、反復処理中に何かを変更するべきではありません。ただし、に変更するfor number in xfor number in x[:]、期待どおりに機能します。この場合、コピーを繰り返し処理しています。

于 2013-04-14T22:23:56.127 に答える
1

反復しているリストを変更しないでください。リストをコピーするか、削除するものの新しいリストを収集することを提案する人もいます。代わりに、残りたいものを集めてください。これは、リストをコピーして、繰り返し処理されていないコピーから削除するよりも高速であり、削除するものを収集してから削除するよりも高速です。

    evens = []
    for number in x:
        if number%2 == 0:
            evens += [number]
    print(evens)
于 2013-04-14T23:11:20.813 に答える