获取在切片列表时选择的索引。

huangapple go评论83阅读模式
英文:

Get indexes chosen when slicing a list

问题

我有一个列表:

things = ["a", "b", "c", "d", "e", "f"]

我还有一个为我提供的切片对象,用于上面的列表。以下是一个示例:

s = slice(-2, None, None)
print(things[-2:])  # ['e', 'f']

我的目标是提取切片影响的具体索引。在这个示例中,那将是:

[4, 5]

有人知道我应该如何更加Pythonic地做到这一点吗?我目前的解决方案是:

print([i for i in range(len(things))]
展开收缩
) # [4, 5]
英文:

I have a list:

things = ["a", "b", "c", "d", "e", "f"]

I also have a slice object provided to me, intended for the list above. Here's an example:

s = slice(-2, None, None)
print(things[-2:])  # ['e', 'f']

My goal is to extract the specific indexes the slice impacts. In this example, that would be:

[4, 5]

Does anyone know how I would go about doing this more pythonically? My current solution is:

print([i for i in range(len(things))]
展开收缩
) # [4, 5]

答案1

得分: 2

这正是slice类的indices方法的目的。

正如内置帮助中所解释的那样:

Help on built-in function indices:

indices(...) method of builtins.slice instance
    S.indices(len) -> (start, stop, stride)
    
    假设有一个长度为len的序列,计算由S描述的扩展切片的起始和停止索引以及步长长度。超出边界的索引将被剪切,与普通切片的处理方式一致。

因此,传递给它将被切片的序列的长度,以获取相应的起始/停止/步长值:

>>> s = slice(-2, None, None)
>>> 
>>> things = ['a', 'b', 'c', 'd', 'e', 'f']
>>> things
展开收缩
['e', 'f'] >>> s.indices(len(things)) (4, 6, 1) >>> x, y, z = s.indices(len(things)) >>> things[x:y:z] ['e', 'f']

这当然可以用来构造相应的值范围:

>>> list(range(*s.indices(len(things))))
[4, 5]

另外,range对象可以直接进行索引和切片,将它们转换为列表也很简单,只需将它们直接传递给list类型即可。因此:

>>> list(range(len(things))
展开收缩
)
[4, 5] >>> list(range(len(things)))
展开收缩
[4, 5]

这对于获取实际索引列表更加简单;在其他上下文中(例如,为自定义类型实现__getitem__时),起始/停止/步长值可能更直接有用。

英文:

This is exactly the purpose of the indices method of the slice class.

As explained in the built-in help:

Help on built-in function indices:

indices(...) method of builtins.slice instance
    S.indices(len) -> (start, stop, stride)
    
    Assuming a sequence of length len, calculate the start and stop
    indices, and the stride length of the extended slice described by
    S. Out of bounds indices are clipped in a manner consistent with the
    handling of normal slices.

Thus, pass it the length of the sequence that will be sliced, in order to get the corresponding start/stop/stride values:

>>> s = slice(-2, None, None)
>>> 
>>> things = ['a', 'b', 'c', 'd', 'e', 'f']
>>> things
展开收缩
['e', 'f'] >>> s.indices(len(things)) (4, 6, 1) >>> x, y, z = s.indices(len(things)) >>> things[x:y:z] ['e', 'f']

Which can of course be used to construct the corresponding range of values:

>>> list(range(*s.indices(len(things))))
[4, 5]

As an aside, range objects can be indexed and sliced directly, and converting them to lists is as easy as passing them directly to the list type. Thus:

>>> list(range(len(things))
展开收缩
) [4, 5] >>> list(range(len(things)))
展开收缩
[4, 5]

This is simpler for getting an actual list of indices; in other contexts (for example, implementing __getitem__ for a custom type) the start/stop/stride values may be more directly useful.

huangapple
  • 本文由 发表于 2023年6月2日 09:37:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76386641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定