[注意:即使使用临时数组(不修改循环数组),代码也没有为列表b
提供正确的答案。]
从列表中删除奇数,请参阅下面的代码。
为什么它适用于列表a
,而不是列表b
?谢谢。
def purify(numbers):
numbers_buf = numbers
for item in numbers:
if item % 2 == 1:
numbers_buf.remove(item)
return numbers_buf
a = [1,2,3,4]
print purify(a)
[2, 4]
b = [4,5,5,4]
print purify(b)
[4,5,4]
答案 0 :(得分:1)
答案 1 :(得分:1)
你正在做两件你可能不应该做的事情,因为他们都在惹麻烦。
永远不会在迭代过程中添加或删除数组中的项目。这会让Python和你感到困惑,而且几乎肯定无法达到预期的效果。
无论如何,你真的不应该修改阵列。该函数没有得到数组的副本;它修改了调用者传入的实际数组。对于所有参与者来说,这可能是令人惊讶的行为:
a = [1,2,3,4]
print purify(a) #=> [2, 4]
print a #=> [2, 4]
您应该构造并返回一个新数组,并且可能更改函数名称以指示(类似于sort
和sorted
内置函数):
def purified(a):
return [n for n in a if n % 2 == 0]
a = [1,2,3,4]
print purified(a) #=> [2, 4]
print a #=> [1, 2, 3, 4]
答案 2 :(得分:1)
numbers_buf = numbers[:] # make a copy not a reference
def purify(numbers):
numbers_buf = numbers[:]
for item in numbers:
if item % 2:
numbers_buf.remove(item)
return numbers_buf
迭代列表时操作/删除元素会改变元素的索引,numbers_buf = numbers
创建对numbers
列表的引用,基本上是指向同一个对象的指针,所以从一个删除,删除来自两者。
使用numbers[:]
创建一个副本/新对象。
运行以下功能以帮助说清楚,看看3和4是如何做跑步者的:
def purify(numbers):
numbers_buf = numbers
should_be = numbers[:]
for ind, item in enumerate(numbers):
print("{} should be at {}, is at {}".format(item,should_be.index(item),ind))
if item % 2:
numbers_buf.remove(item)
return numbers_buf
print(purify([4,5,4,7,3,1]))
如果您确实想使用list comp来修改原始对象:
def purify(numbers):
numbers[:] = [x for x in numbers if not x % 2]
return numbers
您还可以使用reversed
:
def purify(numbers):
for item in reversed(numbers):
if item % 2:
numbers.remove(item)
return numbers
答案 3 :(得分:1)
你的问题源于这样一个事实:你没有像你想要的那样循环遍历不同的列表。您希望避免在循环时从列表中删除某些内容,这就是您使用numbers_buf = numbers
但请注意,未创建新列表:
In [73]: numbers = list(range(10))
In [74]: numbers
Out[74]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [75]: id(numbers)
Out[75]: 4469310792
In [76]: numbers_buf = numbers
In [77]: id(numbers)
Out[77]: 4469310792
In [78]: id(numbers_buf)
Out[78]: 4469310792
In [79]: id(numbers_buf) == id(numbers)
Out[79]: True
In [80]: numbers
Out[80]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [81]: numbers_buf
Out[81]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [82]: numbers.append(10)
In [83]: numbers_buf
Out[83]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
最后请注意,当我将10
追加到numbers
时,它也会附加到numbers_buf
。这是因为当您执行numbers_buf = numbers
时,python不会创建包含数字的新列表;它只是创建名称numbers_buf
,并使其指向numbers
指向的完全相同的结构(这就是所有id(numbers)
内容所显示的内容)。您可以按如下方式解决此问题:
In [84]: numbers_buf_new = numbers[:]
In [85]: id(numbers_buf_new)
Out[85]: 4469329032
In [86]: id(numbers_buf_new) == id(numbers)
Out[86]: False
In [87]: numbers
Out[87]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [88]: numbers_buf_new
Out[88]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [89]: numbers.append(11)
In [90]: numbers
Out[90]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
In [91]: numbers_buf_new
Out[91]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 4 :(得分:0)
如果你想保留使用remove方法并返回相同的列表,你可以试试这个:
def purify(numbers):
for item in numbers:
if item % 2 == 1:
count = numbers.count(item)
for i in range(count):
numbers.remove(item)
return numbers
答案 5 :(得分:0)
您的功能正在以您预期的方式工作。 for循环取第一个元素,而不是第二个元素,所以当你删除一个元素时,其他元素会改变它们的位置,并且当它们前面有另一个奇数时,可以跳过它(这种情况会发生在你的情况下)。
您可以改用此代码:
def purify(numbers):
return [x for x in numbers if x % 2 == 0]
分别为a和b返回[2,4] [4,4]