为什么
range(0,10).remove(1)
不起作用?
我知道问题很简短,但我不知道为什么这个东西不起作用.. 是否可以将其写在一行?
答案 0 :(得分:7)
x = range(0, 10)
将返回列表或range
对象(取决于您的Python版本)。
x = range(0, 10).remove(1)
将返回None
,因为list.remove
将修改列表就地,因此返回None
。您的列表已创建并且值1
已删除,但由于它从未分配给任何内容,因此会进行垃圾回收。
x = range(0, 10).remove(1)
将返回AttributeError
,因为range
objects没有remove
方法。如果使用list(range(0, 10)).remove(1)
将其转换为列表,则会遇到与Python 2相同的问题。
获得所需内容的方法是使用list comprehension。在列表推导中,您将迭代range(0, 10)
但使用if
语句仅添加非1的值,例如:
x = [i for i in range(0, 10) if i != 1]
# [0, 2, 3, 4, 5, 6, 7, 8, 9]
答案 1 :(得分:2)
因为remove()
方法操作"就位",并且不会返回任何内容。
答案 2 :(得分:1)
问题是remove
是就地操作,因此返回None
。
确实按照您的想法执行操作:从0
创建一个列表到9
,然后删除元素1
,但这是一个未分配给它的临时列表任何变量。
作为替代方案,列表理解可以实现这个
>>> [i for i in range(0,10) if i != 1]
[0, 2, 3, 4, 5, 6, 7, 8, 9]
答案 3 :(得分:0)
为什么remove
不起作用已被涵盖。
我想提出list comprehension
方法的替代方法:
In [1]: filter(lambda x:x!=1, range(10))
Out[1]: [0, 2, 3, 4, 5, 6, 7, 8, 9]
虽然列表理解被认为是更加pythonic,但filter
有时可能更接近于表达潜在的问题。
答案 4 :(得分:0)
结果为None
,因为list.remove()
并未返回任何内容。您可以使用lambda
函数和or
运算符来解决此问题。
在Python 2中,这个单线程可以工作:
(lambda lst=range(0, 10): lst.remove(1) or lst)()
或Python 3中的这个:
(lambda lst=list(range(0, 10)): lst.remove(1) or lst)()
两者的执行速度都比使用列表推导更快(虽然它不太可读):
> python -mtimeit "(lambda lst=range(0, 10): lst.remove(1) or lst)()"
1000000 loops, best of 3: 0.467 usec per loop
> python -mtimeit "[i for i in range(0, 10) if i != 1]"
1000000 loops, best of 3: 0.815 usec per loop
> c:\python3\python -mtimeit "(lambda lst=list(range(0, 10)): lst.remove(1) or lst)()"
1000000 loops, best of 3: 0.817 usec per loop
> c:\python3\python -mtimeit "[i for i in range(0, 10) if i != 1]"
1000000 loops, best of 3: 1.17 usec per loop