我不允许使用.remove()函数来删除列表中的偶数,并且规范说:您将修改原始列表,因此其id()不得更改。这就是我所拥有的:
def remove_evens(xs):
for i in range(len(xs)):
for x in xs:
if x%2==0:
del xs[i]
return xs
例如,如果我测试函数并输入xs = [1,2,3,4,5],则返回[3,5]。我不知道1为什么不回来
答案 0 :(得分:2)
那是因为你在列表上进行迭代并同时修改它。这意味着索引i
并不总是正确的,因为您刚刚从列表中删除了一个元素。这导致跳过元素,这就是1
不存在的原因。
你可以这样做:
def remove_evens(xs):
return [x for x in xs if x % 2 != 0]
这使用list comprehension创建没有偶数的列表。如果您需要修改现有列表,您可以这样做:
def remove_evens(xs):
to_remove = []
for i, x in enumerate(xs):
if x % 2 == 0:
to_remove.append(i)
for j in to_remove:
del xs[j]
return xs
这会创建一个列表to_remove
,用于跟踪需要删除的元素的位置。
答案 1 :(得分:2)
也许这样的事情对你有用。
>>> xs = [1,5,123,6,2,34]
>>> id(xs)
35519496L
>>> lastidx = len(xs) - 1
>>> for i, x in enumerate(reversed(xs)):
... if x%2==0:
... del xs[lastidx-i]
...
>>> xs
[1, 5, 123]
>>> id(xs)
35519496L
这是线性时间,因为它只在列表上迭代一次。当您向后遍历列表时,您可以自由删除元素,而无需修改尚未循环的未来元素的索引。您也可以看到,此方法的列表ID不会改变。 :)
以下是另一种仅使用range
/ xrange
和len
执行相同操作的方法。
>>> xs = [1,5,123,6,2,34]
>>> for i in range(len(xs)-1,-1,-1):
... if xs[i]%2==0:
... del xs[i]
...
>>> xs
[1, 5, 123]
两种方式都做同样的事情,无论你决定使用哪种方式都是偏好/个人风格。
答案 2 :(得分:0)
当您在列表上进行迭代时,从列表中删除项目是个坏主意。
您可以通过以下几种方式实现目标:
>>> def deleteEvens(L):
... dels = []
... for i,x in enumerate(L):
... if not x%2:
... dels.append(i)
... for d in dels[::-1]:
... L.pop(d)
...
>>> L
[1, 2, 3, 4, 5]
>>> deleteEvens(L)
>>> L
[1, 3, 5]
OR
>>> L = [1,2,3,4,5]
>>> odds = [i for i in L if i%2]
>>> odds
[1, 3, 5]
OR
>>> def delEvens(L):
... dels = []
... for i,x in enumerate(L):
... if not x%2:
... dels.append(i)
... for d in dels[::-1]:
... del L[d]
...
>>> L = [1,2,3,4,5]
>>> delEvens(L)
>>> L
[1, 3, 5]