私の Python 2.7.2 IDLE インタープリターでは:
>>> mylist = [1, 2, 3, 4, 5]
>>> for item in mylist:
mylist.remove(item)
>>> mylist
[2, 4]
なんで?
私の Python 2.7.2 IDLE インタープリターでは:
>>> mylist = [1, 2, 3, 4, 5]
>>> for item in mylist:
mylist.remove(item)
>>> mylist
[2, 4]
なんで?
これは、リストを反復処理するときに、 python がリスト内のインデックスを追跡するためです。代わりに次のコードを検討してください。
for i in range(len(mylist)):
if i >= len(mylist):
break
item = mylist[i]
mylist.remove(item)
これを追跡すると (これは基本的に Python がコードで行っていることです)、リスト内の項目を削除すると、右側の数値が左に 1 つシフトして、削除したときに左の空白を埋めることがわかります。アイテム。正しい項目は現在 indexi
にあるため、実際には反復で表示されることはありません。これは、次に発生するi
のは for ループの次の反復のためにインクリメントするためです。
次に、少し賢いことを説明します。代わりに、リストを逆方向に反復すると、リストがクリアされます。
for item in reversed(mylist):
mylist.remove(item)
ここでの理由は、for ループの反復ごとにリストの末尾から項目を削除しているためです。常に最後からアイテムを取り出しているため、何もシフトする必要はありません (リストが一意であると仮定すると、リストが一意でない場合、結果は同じになりますが、引数は少し複雑になります)。
もちろん、リストからすべてのアイテムを削除する場合は、非常に簡単に行うことができます。
del mylist[:]
またはスライスの割り当てでも:
mylist[:] = []
(リストのセグメントを同じ長さである必要さえない他のアイテムに置き換えると便利な場合があるため、後者について言及します)。
これは、リストを反復しながらリストを変更しているためです。代わりに、浅いコピーを反復します。
>>> mylist = [1, 2, 3, 4, 5]
>>> for item in mylist[:]: #use mylist[:] or list(mylist)
mylist.remove(item)
...
>>> mylist
[]
問題は、リストを繰り返しながらリストを変更していることです。代わりにリスト内包表記を使用してください。
mylist = [1, 2, 3, 4, 5]
mylist = [x for x in mylist if condition(x)]
リストをループしている間にリストを変更していますが、これは非常に悪い習慣です。
のディープ コピーを使用するmylist
mylist = [1, 2, 3, 4, 5]
l = [k for k in mylist] # deep copy
for i in range(len(mylist)):
mylist.remove(l[i])
print
print mylist
>>> mylist = [1, 2, 3, 4, 5]
>>> for item in mylist:
mylist.remove(item)
このループでは:最初に0番目の要素(1)をアイテムとして取り、mylist.soから削除します。その後、mylistは[2,3,4,5]になりますが、ポインターは新しい要素の1番目の要素になりますmylist ([2,3,4,5]) は 3 であり、3 を削除します。したがって、2 はリストから削除されません。
それが、完全な操作の後に [2,4] が残る理由です。
using for loop:-
>>>for i in range(len(mylist)):
mylist.remove(mylist[0])
i-=1
>>>mylist
[]
while ループを使用してこれを行うことができます。
>>>mylist = [1, 2, 3, 4, 5]
>>>while (len(mylist)>0):
mylist.remove(mylist[0])
print mylist