为什么`for x in list[None:None]:`可以使用?

11 投票
3 回答
581 浏览
提问于 2025-04-18 01:43

我有一个脚本,它试图通过二分查找来读取一个子集的起始和结束点,然后用这些值来创建一个切片,以便进行进一步处理。

我注意到,当这些变量没有被设置(也就是说,搜索返回了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 个回答

1

None 通常用来表示“没有提供参数”,这样你就可以把这个信息传递给一个函数。你会经常看到函数或方法是这样声明的:

def f(p=None):
    if f is None:
        f = some_default_value()

我想这让选择变得很清楚:使用 None 可以告诉切片器使用它的默认值。

3

我也认为 list[None:None] 会被解释为 list[:]。这个特性很方便,因为你可以这样做:

return list[some_params.get('start'):some_params.get('end')]

如果列表切片不支持 None,你就得自己检查 startend 是否为 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中并不是这样 :).

16

因为 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 作为默认值在这里是完全合理的。

撰写回答