0

ウィンクルソンはここで非常に単純な質問について助けを求めています...私は現時点ではかなり疲れていますが、この問題で何が間違っているのかを理解したいと思います:) もちろん、問題を解決する他の方法素晴らしいでしょう!前もって感謝します!

質問:


アイテムを削除

リストと値を受け取り、指定された値の出現箇所をすべて削除したリストを返す関数を作成します。

かなり単純ですよね?手のひらで顔を合わせると頭が痛くなりそうです... とにかくここに呼び出しがあります。

通話:


>>> remove(['a','b','c','d','e'],'e') 
['a','b','c','d'] 
>>> remove([4,2,7,6,7,8,3,1,3,5],3) 
[4,2,7,6,7,8,1,5] 
>>> remove([4,4,4,4],4) 
[] 
>>> remove([1,2,3,4,5,6,7],'hi') 
[1,2,3,4,5,6,7]

私のコード:


def remove(l,o): #l is list, o is object
    for i in l:
        if i == o: #If the current item is the object to be removed...
            l.remove(o) #Remove the object      
    return l #Finally return the list.

だから...ここに問題があります:


呼び出し: remove([4,4,4,4],4)

返されるはず:[]

返されるもの: [4, 4]

正: 誤り


だから...誰かが何が起こっているのか知っているなら、あなたの知識を共有してくれたら素晴らしいでしょう! さらに、他の解決方法も同様に素晴らしいでしょう。ヒントが漠然としすぎていなければ、それも素晴らしいでしょう。とにかく、よろしくお願いします!- ウィンクルソン

Ps 私はまだ初心者のプログラマーなので、あまり私に厳しくしないでください :P どうもありがとう!

4

5 に答える 5

3

あなたの問題は、リストを変更すると同時にリストを反復しようとしていることです。最初の反復では:

l = [4, 4, 4, 4]

Python は l[0] を見て、それを削除します。

リストは次のとおりです。

l = [4, 4, 4]

l[0] を行ったばかりなので、Python は l[1] を見たいと思っています。しかし、リストが変更されたため、l[1] にあった値は代わりに l[0] にあり、スキップされます。

1 つのオプションは、新しいリストを作成することです。

def remove(l,o):  
    new_list = []  
    for i in l:        
        if i != o:
            new_list.append(i)       
    return new_list

これは一般的な種類の操作であるため、Python では、非常に便利な「リスト内包表記」を使用して同じことを行うことができます。

def remove(l,o)
    new_list = [item for item in l if item != o]

(ちなみに、1 文字の変数名を使用するのは一般的に悪い考えです。特に、"o" と "l" は、それぞれ "0" と "1" と簡単に間違えられる可能性があります。)

于 2012-11-27T18:37:52.887 に答える
2

list.remove()remove() を呼び出すたびに残りの要素をリストに沿って移動する必要があるため、アイテムを 1 つずつ削除するのは効率的ではありません。必要な要素だけを含む新しいリストを作成すると、はるかに効率的になり、ループ中にリストを変更するという問題が回避されます。

このバリアントは、質問で行っているようにリストを変更します

def remove(L, o):
    L[:] = (item for item in L if item != o)
    return L

非インプレースバリアントは新しいリストを返します

def remove(L, o):
    return [item for item in L if item != o]
于 2012-11-27T18:44:47.707 に答える
1

リストを繰り返し処理すると同時にリストを変更しています。これは、リスト反復子が基になるリストと同期しなくなる可能性が高いことを意味します。

最初は、リストは次のようになります。

[4, 4, 4, 4]
 ^-iterator

最初の要素をチェックすると、イテレータは次の要素に移動しました:

[4, 4, 4, 4]
    ^-iterator

呼び出し時remove(この動作は保証されていないことに注意してください):

[4, 4, 4, 4]
 ^  ^-iterator
 |
 `this item is removed

呼び出した後remove:

[4, 4, 4]
    ^-iterator

removeまた、の観点から実装しても、remove多くの点数が得られる可能性は低いです。適切な項目だけを含む新しいリストを作成してみてください。

于 2012-11-27T18:36:00.143 に答える
1

あなたは非常に近いですが、関数を使用するだけでなく、新しいリストを作成する方が良い場合がありますremove。つまり、

def remove(l,o): #l is list, o is object
    newlist = []
    for i in l:
        if i != o: #If the current item is the object to be removed...
            newlist.append(i)      
    return newlist #Finally return the list.
于 2012-11-27T18:38:45.110 に答える
1

リストの要素をループしているときにリストを変更しないでください。http://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/で理由を説明しています。

リスト内包表記を使用して新しいリストを作成し、それを返します: http://docs.python.org/tutorial/datastructures.html#list-comprehensions

于 2012-11-27T18:35:01.317 に答える