2

次の 2 つの例では、2 つの異なる種類のループを使用して、リストから負の要素を削除しようとしています。

最初に通常のループを使用してみましfor i in listたが、この場合list1.remove(elm)、リストのサイズが1要素減ります。したがって、次のループでは、2 番目の要素が最初の要素の位置に移動します。if elm < 0そのため、次のループで2 番目の要素がテストされません。したがって、リストからすべての否定的な要素が削除されるわけではありません。

次に、スライスを使用してみました。スライスから理解したのは、一時的なリストを作成することです。だから、私がfor i in list2[:]それを行うと、新しい一時的なものが作成されますlist2 = [-1,3,-2,-5,4,7,8]が、それでも明確な画像が得られませんでした. 全てのマイナス要素を取り除きます。

#!/usr/env/bin
# remove all the negative value from the list.
list1 = [-1,3,-2,-5,4,7,8]
list2 = [-1,3,-2,-5,4,7,8]

# Looping through the list.
for elm in list1:
    if elm < 0:
        list1.remove(elm)
print 'list1: ', list1

# Looping through the list using slice.
for elm in list2[:]:
    if elm < 0:
        list2.remove(elm)
print 'list2: ', list2

Output:-python slice.py
list1: [3, -5, 4, 7, 8]
list2: [3, 4, 7, 8]
4

4 に答える 4

4

問題は、リストを反復処理して同時に変更すると、悪い結果が生じる可能性があることです。

たとえば、インデックス 2 にいて、そこから負の数を削除すると、インデックス 3 の値がインデックス 2 に移動します。次の反復では、インデックス 3 に移動しますが、古いインデックス 3 の値はスキップします (新しいインデックス 2)。

スライスはコピーを作成するため、ネガを削除しても変更されません。

参考までに、別の可能性は

filter(lambda x: x >= 0, list2)

また

[x for x in list2 if x >= 0]

編集:

これが反復です。

(index)        list1            elem
   0      [-1,3,-2,-5,4,7,8]     -1
   1      [3,-2,-5,4,7,8]        -2
   2      [3,-5,4,7,8]            4
   3      [3,4,7,8]               8

同じものを反復して変更していたために、いくつかの値を見逃していたことがわかりますか?

コピーを作成するスライスを使用すると、

(index)        (copy)             list2            elem
   0     [-1,3,-2,-5,4,7,8]  [-1,3,-2,-5,4,7,8]     -1
   1     [-1,3,-2,-5,4,7,8]  [3,-2,-5,4,7,8]         3
   2     [-1,3,-2,-5,4,7,8]  [3,-2,-5,4,7,8]        -2
   3     [-1,3,-2,-5,4,7,8]  [3,-5,4,7,8]           -5
   4     [-1,3,-2,-5,4,7,8]  [3,4,7,8]               4
   5     [-1,3,-2,-5,4,7,8]  [3,4,7,8]               7
   6     [-1,3,-2,-5,4,7,8]  [3,4,7,8]               8

スキップせずに、7 つの値すべてを反復処理します。

参考までに、またはlist2[:]と同等です。list2[0:len(list2):1]list(list2)

于 2013-11-03T03:14:18.230 に答える
1

ここでリスト内包表記を使用して、保持したい要素を含む新しいリストを作成します。

numbers = [-1, 3, -2, -5, 4, 7, 8]
positive = [n for n in numbers if n >= 0]

または、スライス割り当てを介して新しいシーケンスを既存のシーケンスに再割り当てします。

numbers = [-1, 3, -2, -5, 4, 7, 8]
numbers[:] = (n for n in numbers if n >= 0)
于 2013-11-03T03:14:54.903 に答える
1

リスト 1 では、python は反復処理中にアイテムを削除しています。これは、ご覧のとおり、予期しない結果につながる可能性があります。時計:

for elm in list1:
    if elm < 0:
        list1.remove(elm)
    print list1

これは印刷されます:

[3, -2, -5, 4, 7, 8]
[3, -5, 4, 7, 8]
[3, -5, 4, 7, 8]
[3, -5, 4, 7, 8]
[3, -5, 4, 7, 8]

そのため、アイテムを削除した後に python に戻ると、for elm in list1その後のアイテムではなく、前のアイテム ( 3) に移動します。したがって、ループ。

コピーを作成すると、list2[:]実際には反復処理ではlist2なく単なるコピーであるため、アイテムを削除しても、反復処理しているものは何も削除されません。

于 2013-11-03T03:15:32.157 に答える
0

スライス演算子は、操作しているリストをコピーして、正確な結果に導きます。

于 2013-11-03T03:29:59.950 に答える