2012-05-11 13 views
0

コードから重複した値を削除します最初のリスト

li = [32,45,23,66,66,89,27] 
print li 
for k in li: 
    if k == 66: 
     li.remove(k) 
print li 

結果:

> [32, 45, 23, 66, 66, 89, 27] 

> [32, 45, 23, 66, 89, 27] 

ここでは私の質問です:私は最初を削除すると、二番目およびその他の項目になります1つ前のインデックスに移動し、次のkはとなります。 2番目のはまだそこにあります。どうすれば削除できますか?

+2

繰り返し処理中にアイテムを削除しないでください。リスト内包を使用して正しい値で新しいリストを作成する方がよいでしょう。 – jamylak

答えて

2

この問題が発生する理由を理解するには、私の答えをLoop problem while iterating through a list and removing recurring elementsにしてください。この場合

、あなただけ行うことができます。

li = [item for item in li if item != 66] 

新しいリストを作成します。

removeをたくさんする必要がある場合はリストの解読も速くなります。removeはリスト全体を走査しなければならず、リスト内包はリスト全体を1回だけ走査するためです。

+0

あなたの素晴らしいリンクありがとう! – sashimi

0

あなたがしたいことはthisだと思います。だからあなたの場合には:もちろん

li = [32,45,23,66,66,89,27] 
print li 
li[:] = [x for x in li if x != 66] 
print li 

あなたは常に逆転liを繰り返すことができは、forループの正常でそれをやりたい場合:

li = [32,45,23,66,66,89,27] 
print li 
for k in reversed(li): 
    if k == 66: 
     li.remove(k) 
print li 

しかし、通知を、これは非常に非効率的であること。 removeは、最初の発生時にを検索して削除するためです。したがって、リストを何度も効果的に繰り返すことができます。

+0

彼は同じ実際のリストオブジェクトを維持する必要があるかどうかわかりません。彼はおそらくしません。 – agf

+0

古いリストを変更する理由はありません。この場合、リビルド名 'li'は実際にはわずか(約10%)速いです。それは不必要なコードの複雑さを避けることは言うまでもありません。 –

3

これを行うための最も一般的な方法ではなく、元のリストよりも、リストのコピーを反復処理することです:

for k in li[:]: 
    #do stuff 

私はしかし、リストの内包表記を使用することを好む:

[k for k in li if k != 66] 
+1

あなたの言葉は私にはあまり明確ではありませんが、リストの理解はリストを変更しません。 – jamylak

+0

@jamylak:うん、あなたの権利、私はちょうど私が書いたものを読んで:P –

関連する問題