16

私は現在Pythonでプログラムを開発していますが、言語のforeachループ、またはリスト構造に問題があることに気づきました。プログラムと一般的な例の両方で同じ誤った動作が発生するため、単純化するために問題の一般的な例を示します。

x = [1,2,2,2,2]

for i in x:
    x.remove(i)

print x        

さて、ここでの問題は単純ですが、このコードはリストからすべての要素を削除することになっていると思います。問題は、実行後、リストに残っている要素が常に2つあることです。

私は何が間違っているのですか?事前にすべての助けをありがとう。

編集:私はリストを空にしたくありません、これは単なる例です...

4

7 に答える 7

37

これはPythonで十分に文書化された動作であり、繰り返されるリストを変更することは想定されていません。代わりにこれを試してください:

for i in x[:]:
    x.remove(i)

[:]は、の「スライス」を返します。これにはx、たまたまそのすべての要素が含まれているため、事実上、のコピーになりxます。

于 2009-04-12T20:36:58.083 に答える
11

要素を削除し、forループが次のインデックスに挿入されると、要素をスキップします。

逆にそれをしなさい。または、あなたの本当の問題を述べてください。

于 2009-04-12T20:37:18.753 に答える
5

大まかに言って、あなたが書くとき、私は思います:

for x in lst:
    # loop body goes here

内部的には、Pythonは次のようなことをしています。

i = 0
while i < len(lst):
    x = lst[i]
    # loop body goes here
    i += 1

ループ本体に挿入するlst.remove(x)と、おそらく、結果が得られる理由がわかりますか?

基本的に、Pythonは移動ポインターを使用してリストをトラバースします。ポインタは、最初の要素を指すことから始まります。次に、最初の要素を削除して、2番目の要素を新しい最初の要素にします。次に、ポインタが新しい2番目(以前は3番目)の要素に移動します。等々。(サンプルリストとして[1,2,2,2,2]の代わりに[1,2,3,4,5]を使用すると、より明確になる場合があります)

于 2009-04-13T02:43:03.287 に答える
3

使ってみませんか:

x = []

繰り返し処理しているのと同じ配列を変更していることが原因である可能性があります。

配列をクリアしたい場合は、Chris-JesterYoungの回答を試してください。

于 2009-04-12T20:38:05.270 に答える
3

私はこれが受け入れられた答えのある古い投稿であることを知っていますが、それでもやってくるかもしれない人のために...

以前のいくつかの回答は、反復中に反復可能オブジェクトを変更することは悪い考えであることを示しています。しかし、何が起こっているのかを強調する方法として...

>>> x=[1,2,3,4,5]
>>> for i in x:
...     print i, x.index(i)
...     x.remove(i)
...     print x
...
1 0
[2, 3, 4, 5]
3 1
[2, 4, 5]
5 2
[2, 4]

うまくいけば、ビジュアルが明確にするのに役立ちます。

于 2016-08-05T22:01:31.490 に答える
1

休憩条件についてはジョン・フーヒに同意します。Chris Jester-Youngが提案したように、リストのコピーをトラバースすると、remove()メソッドで機能します。しかし、特定のアイテムをpop()する必要がある場合は、Erikが述べたように、逆の作業を繰り返します。この場合、操作はその場で実行できます。例えば:

def r_enumerate(iterable):
    """enumerator for reverse iteration of an iterable"""
    enum = enumerate(reversed(iterable))
    last = len(iterable)-1
    return ((last - i, x) for i,x in enum)

x = [1,2,3,4,5]
y = []
for i,v in r_enumerate(x):
    if v != 3:
        y.append(x.pop(i))
    print 'i=%d, v=%d, x=%s, y=%s' %(i,v,x,y)


またはxrangeを使用:

x = [1,2,3,4,5]
y = []
for i in xrange(len(x)-1,-1,-1):
    if x[i] != 3:
        y.append(x.pop(i))
    print 'i=%d, x=%s, y=%s' %(i,x,y)
于 2009-11-07T17:12:18.920 に答える
0

リストからデータを除外する必要がある場合は、リスト内包表記を使用することをお勧めします。

newlist = [x for x in oldlist if x%2]

たとえば、整数リストからすべての偶数をフィルタリングします

于 2021-07-29T20:48:25.800 に答える