Python:从列表中删除奇数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14275118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: remove odd number from a list
提问by neo0
I wrote a function to remove odd number from a list, like that:
我编写了一个函数来从列表中删除奇数,如下所示:
def remove_odd(l):
for i in l:
if i % 2 != 0:
l.remove(i)
print l
return l
remove_odd([4,5,4])
remove_odd([4,5,4,7,9,11])
remove_odd([4,5,4,7,9,11,12,13])
It returns:
它返回:
[4, 4]
[4, 4, 9]
[4, 4, 9, 12]
-> wrong
-> 错
but when I change to remove even number:
但是当我更改以删除偶数时:
def remove_even(l):
for i in l:
if i % 2 == 0:
l.remove(i)
print l
return l
remove_even([4,5,4])
remove_even([4,5,4,7,9,11])
remove_even([4,5,4,7,9,11,12,13])
The answer is OK:
答案是可以的:
[5]
[5, 7, 9, 11]
[5, 7, 9, 11, 13]
What is wrong with the remove_odd() func? I know people usually create the second list inside the func then append even number to that list, but can we solve this exercise with list.remove() ?
remove_odd() 函数有什么问题?我知道人们通常在 func 中创建第二个列表,然后将偶数附加到该列表中,但是我们可以用 list.remove() 解决这个练习吗?
Thank you!
谢谢!
采纳答案by Althorion
Your function is working in another way than you would expect. The forloop takes first element, than second etc., so when you remove one element, others change their positions and can be skipped by it (and that happens in your case) when they are preceded by another odd number.
您的函数以超出您预期的方式工作。该for回路采用第一个元素,比第二等,所以当你删除一个元素,别人改变自己的位置,并且可以通过它可以跳过(和你的情况发生这种情况),当他们被另一个奇数开头。
If you insist on using .remove()method, you must operate on a copy instead, like this:
如果您坚持使用.remove()方法,则必须改为对副本进行操作,如下所示:
def remove_odd(1):
for i in l[:]:
if i % 2 != 0:
l.remove(i)
return l
(l[:]is a shallow copy of list l)
(l[:]是列表的浅拷贝l)
However, I think using list comprehension would be much clearer:
但是,我认为使用列表理解会更清楚:
def remove_odd(l):
return [x for x in l if x % 2 == 0]
回答by Abhijit
What is wrong with the remove_odd() func?
remove_odd() 函数有什么问题?
You are iterating over a list while changing its size. This is causing it to skip one or more elements
您正在迭代列表,同时更改其大小。这导致它跳过一个或多个元素
Why don't you use list comprehension. Its more Pythonic, and readable
为什么不使用列表理解。它更 Pythonic 和可读
def remove_odd(l):
return [e for e in l if e % 2 == 0]
remove_odd([4,5,4,7,9,11])
[4, 4]
Similarly you can write your remove_even routine
同样,您可以编写 remove_even 例程
def remove_even(l):
return [e for e in l if e % 2]
remove_even([4,5,4,7,9,11])
[5, 7, 9, 11]
回答by Ashwini Chaudhary
You are trying to modify a list while you're iterating over it.
您正在尝试在迭代列表时修改列表。
Try something like this:
尝试这样的事情:
In [28]: def remove_odd(l):
return [x for x in l if x%2 == 0]
....:
In [29]: remove_odd([4,5,4,7,9,11])
Out[29]: [4, 4]
In [30]: remove_odd([4,5,4,7,9,11,12,13])
Out[30]: [4, 4, 12]
or to fix your your code only, you should iterate over l[:].
或仅修复您的代码,您应该迭代l[:].
l[:]returns a shallow copy of lwhich is equivalent to list(l).
l[:]返回l其等价于的浅拷贝list(l)。
In [38]: def remove_odd(l):
for i in l[:]:
if i % 2 != 0:
l.remove(i)
return l
....:
In [39]: remove_odd([4,5,4,7,9,11,12,13])
Out[39]: [4, 4, 12]
In [40]: remove_odd([4,5,4,7,9,11])
Out[40]: [4, 4]
回答by Dmitry Zagorulkin
the best way to modify entire list is using it's copy:
修改整个列表的最佳方法是使用它的副本:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l=range(10)
>>> type(l)
<type 'list'>
>>> l[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> type(l[:])
<type 'list'>
>>>
From off docs:
从关闭文档:
If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:
如果您需要在循环内修改您正在迭代的序列(例如复制所选项目),建议您先制作一个副本。迭代序列不会隐式地复制。切片符号使这特别方便:
>>>>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
http://docs.python.org/2/tutorial/controlflow.html
http://docs.python.org/2/tutorial/controlflow.html
And specifically for your example:
特别是对于您的示例:
def remove_odd(l):
for i in l[:]:
if i % 2:
l.remove(i)
return l
works just fine.
工作得很好。
回答by Thorsten Kranz
Python has a built-in method for this: filter
为此,Python 有一个内置方法: filter
filtered_list = filter(lambda x: x%2==0, input_list)
Be careful in Python 3, as here filter is only a generator, so you have to write:
在 Python 3 中要小心,因为这里的 filter 只是一个生成器,所以你必须写:
filtered_list = list(filter(lambda x: x%2==0, input_list))
回答by Holger
You can understand what's happening if you use enumeratein your example.
如果您enumerate在示例中使用,您可以了解发生了什么。
def remove_odd(l):
for n, i in enumerate(l):
print n, i
if i % 2 != 0:
l.remove(i)
print l
return l
remove_odd([4,5,4,7,9,11])
It gives the result:
它给出了结果:
0 4
1 5
2 7
3 11
[4, 4, 9]
So in the first and second case the for loop uses the right values 4 and 5. But you remove the 5 from l. Then in the third step you call 7 instead of the 4 on third position. Therefore it's best to copy l, as already suggested by other answers.
因此,在第一种和第二种情况下,for 循环使用正确的值 4 和 5。但是您从l. 然后在第三步,你在第三个位置跟注 7 而不是 4。因此l,正如其他答案所建议的那样,最好复制。
回答by vinay hegde
you can try like this ..
你可以试试这样..
def remove_odd(l):
a=[]
for i in range(len(l)):
if(l[i]%2 ==0):
a.append(l[i])
return a
print remove_odd([1,2,2,6,4,1,3])

