为什么`for x in list[None:None]:`可以使用?
我有一个脚本,它试图通过二分查找来读取一个子集的起始和结束点,然后用这些值来创建一个切片,以便进行进一步处理。
我注意到,当这些变量没有被设置(也就是说,搜索返回了None)时,代码仍然会运行。最后我发现,从None到None的切片就像是在查看整个列表一样(见下面的例子)。
#! /usr/bin/env python
list = [1,2,3,4,5,6,7,8,9,10]
for x in list[None:None]:
print x
有没有人知道为什么选择将list[None:None]
视为list[:]
,至少我觉得是这样(如果我错了请纠正我)。我个人认为在这种情况下抛出一个类型错误(TypeError)会更好。
3 个回答
None
通常用来表示“没有提供参数”,这样你就可以把这个信息传递给一个函数。你会经常看到函数或方法是这样声明的:
def f(p=None):
if f is None:
f = some_default_value()
我想这让选择变得很清楚:使用 None
可以告诉切片器使用它的默认值。
我也认为 list[None:None]
会被解释为 list[:]
。这个特性很方便,因为你可以这样做:
return list[some_params.get('start'):some_params.get('end')]
如果列表切片不支持 None
,你就得自己检查 start
和 end
是否为 None
:
if some_params.get('start') and some_params.get('end'):
return list[some_params.get('start'):some_params.get('end')]
elif some_params.get('start'):
return list[some_params.get('start'):]
elif end:
return list[:some_params.get('end')]
else:
return list[:]
幸运的是,在Python中并不是这样 :).
因为 None
是切片位置的 默认值。你可以使用 None
,也可以完全不写这个值,这样系统会自动帮你填上 None
。
None
是默认值的原因是你可以使用负数步长,这样默认的开始和结束位置就会 改变。比如,比较一下 list[0:len(list):-1]
和 list[None:None:-1]
。
在 Python 的标准库中,None
用来表示“未指定的值”;这次也不例外。
注意,如果你的类实现了 object.__getitem__
钩子,那么你会得到一个 slice()
对象,它的开始、结束和步长属性也会被设置为 None
:
>>> class Foo(object):
... def __getitem__(self, key):
... print key
...
>>> Foo()[:]
slice(None, None, None)
因为 Foo()
甚至没有实现 __len__
,所以使用 None
作为默认值在这里是完全合理的。