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],并被跳过。

一种选择是在你去的时候建立一个新的列表:

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() 时都需要沿列表移动剩余元素。仅使用您想要的元素创建一个新列表效率更高,并且避免了在循环遍历列表时修改列表的问题。

正如您在问题中所做的那样,此变体会修改列表

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

您不应该在遍历其元素时改变列表。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 回答
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 回答