Dolda2000 の回答は主な質問をうまくカバーしていますが、他に 3 つの問題があります。
index(n)
ループ内で使用することfor n in a
は、ほとんど常に悪い考えです。
それは間違っています:
a = [1, 2, 1, 2]
for n in a:
print(a.index(n))
これは0
、次に1
、そして0
再び出力されます。なんで?さて、3 番目の値は1
です。a.index(1)
リストの最初のインデックスです1
。それは0
、そうではありません2
。
また、遅い: th の値を見つけるには、リストの最初の要素i
をチェックする必要があります。i
これにより、単純な線形 (高速) アルゴリズムが 2 次 (低速) アルゴリズムに変わります。
幸いなことに、Python には、必要なことを正確に行うための優れたツールがありますenumerate
。
for i, n in enumerate(a):
print(i)
または、値がまったく必要ない場合は、インデックスのみを使用します。
for i in len(range(a)):
print(i)
(これは、少なくとも 2 回はドキュメントにヒントとして表示され、初心者が見たことのない場所に便利に埋め込まれています。しかし、チュートリアルの早い段階でも詳しく説明されています。)
次に、Dolda2000 が説明したケースを正確にテストしようとしていたようです。
n is a[a.index(n)]
なぜそれがうまくいかなかったのですか?それらが同じオブジェクトであることを証明したのに、削除しても何も起こらなかったのはなぜですか?
変数が値 (他のアドレスへの参照を含む) が格納されるアドレスである C ファミリ言語とは異なり、Python 変数は、別の場所に独自に存在する値にバインドする名前です。したがって、変数は他の変数を参照できませんが、同じ値の名前にすることはできます。このis
式は、2 つの式が同じ値を指定しているかどうかをテストします。つまり、同じ値に対して 2 つの名前があることが証明されました。それらの名前の 1 つを削除しましたが、もう 1 つの名前と値はまだ存在しています。
例は 1000 語の価値があるので、これを実行します。
a = object() # this guarantees us a completely unique value
b = a
print a, b, id(a), id(b), a is b
del b
print a, id(a)
(もちろん、あなたもdel a
の場合、ある時点で Pythonは値を削除しますが、それを確認することはできません。定義により、それを参照する名前がなくなったためです。)
明らかに、反復中にリストから削除することが許可されています。
そうですね。Python では、反復処理中に iterable を変更した場合に何が起こるかを未定義のままにしていますが、組み込みの可変シーケンス (つまりlist
) でfor
何が起こるかを説明する特別な言語dict
があります。しかし、それは aRuntimeError
を上げることを保証できないとどこかに言っていRuntimeError
ます。
したがって、それが のサブクラスまたはサードパーティのシーケンス クラスではなく、 であることがわかっている場合は、反復中にそこから削除することができ、削除する要素が at または to の場合は「スキップ」動作を期待できます。イテレータの左。しかし、その知識の現実的な有効活用を考えるのはかなり難しいです。a
list
list