如果您喜欢Pythonic,我认为
1:3,6,8:10,16这是一个更好的选择,
x:y索引范围的标准符号也是如此,并且语法允许您在对象上使用此符号。注意通话
z[1:3,6,8:10,16]
被翻译成
z.__getitem__((slice(1, 3, None), 6, slice(8, 10, None), 16))
即使这是一个
TypeErrorif
z内置容器,您也可以自由创建将返回合理值的类,例如NumPy的数组。
您可能还会说,按照惯例
5:,它
:5表示无限索引范围(由于Python没有带有负数或无限大的正索引的内置类型,因此有点过分了)。
这是解析器(一个很漂亮的单线代码,有
slice(16, None, None)如下所述的毛刺):
def parse(s): return [slice(*map(int, x.split(':'))) for x in s.split(',')]但是有一个陷阱:
8:10根据定义,它仅包含索引8和9-没有上限。如果这对于您的目的是不可接受的,那么您当然需要其他格式,并且
1-3,6,8-10,16对我来说不错。然后解析器将是
def myslice(start, stop=None, step=None): return slice(start, (stop if stop is not None else start) + 1, step)def parse(s): return [myslice(*map(int, x.split('-'))) for x in s.split(',')]更新: 这是组合格式的完整解析器:
from sys import maxsize as INFdef indices(s: 'string with indices list') -> 'indices generator': for x in s.split(','): splitter = ':' if (':' in x) or (x[0] == '-') else '-' ix = x.split(splitter) start = int(ix[0]) if ix[0] is not '' else -INF if len(ix) == 1: stop = start + 1 else: stop = int(ix[1]) if ix[1] is not '' else INF step = int(ix[2]) if len(ix) > 2 else 1 for y in range(start, stop + (splitter == '-'), step): yield y这也处理负数,所以
print(list(indices('-5, 1:3, 6, 8:15:2, 20-25, 18')))版画
[-5, 1, 2, 6, 7, 8, 10, 12, 14, 20, 21, 22, 23, 24, 25, 18, 19]
还有一种替代方法是使用
...(Python将其识别为内置常数Ellipsis,因此您可以
z[...]根据需要调用它),但我认为
1,...,3,6,8,...,10,16它的可读性较差。



