python slice对象_在Python中从slice对象检索slice的长度

所以看起来slice.indices(n)返回要给range的参数,以获得应该反映在长度序列n的切片中的项索引(尽管没有文档化的编辑:正如@ShadowRanger指出的,它确实是documented)。因此,以下几行的计算值相同:# get some list to work on

my_list = list(range(100))

# slice syntax

print(my_list[1:15:3])

# regular item access

print(my_list[slice(1,15,3)])

# reinvent list slicing

print([my_list[i] for i in range(*slice(1,15,3).indices(len(my_list)))])

如您所见,结果列表的长度与range(*slice(1,15,3).indices(len(my_list)))的长度相同,这取决于slice对象本身以及要切片的序列的长度。这就是为什么len(range(*slice.indices(n)))将在Python 3中给出正确的答案。(range对象是一个生成器,幸运的是它定义了__len__函数,因此它可以提供项目计数,而无需枚举和计数它们。)

如果在python 2中使用大数,可以按照@ShadowRanger的建议复制计算。

range.__len__的原始实现如下:/* Return number of items in range (lo, hi, step). step != 0

* required. The result always fits in an unsigned long.

*/

static unsigned long

get_len_of_range(long lo, long hi, long step)

{

/* -------------------------------------------------------------

If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.

Else for step > 0, if n values are in the range, the last one is

lo + (n-1)*step, which must be <= hi-1. Rearranging,

n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives

the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so

the RHS is non-negative and so truncation is the same as the

floor. Letting M be the largest positive long, the worst case

for the RHS numerator is hi=M, lo=-M-1, and then

hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough

precision to compute the RHS exactly. The analysis for step < 0

is similar.

---------------------------------------------------------------*/

assert(step != 0);

if (step > 0 && lo < hi)

return 1UL + (hi - 1UL - lo) / step;

else if (step < 0 && lo > hi)

return 1UL + (lo - 1UL - hi) / (0UL - step);

else

return 0UL;

}

以及slice.indices:int

PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,

Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)

{

/* XXX support long ints */

if (r->step == Py_None) {

*step = 1;

} else {

if (!PyInt_Check(r->step) && !PyLong_Check(r->step)) return -1;

*step = PyInt_AsSsize_t(r->step);

}

if (r->start == Py_None) {

*start = *step < 0 ? length-1 : 0;

} else {

if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1;

*start = PyInt_AsSsize_t(r->start);

if (*start < 0) *start += length;

}

if (r->stop == Py_None) {

*stop = *step < 0 ? -1 : length;

} else {

if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1;

*stop = PyInt_AsSsize_t(r->stop);

if (*stop < 0) *stop += length;

}

if (*stop > length) return -1;

if (*start >= length) return -1;

if (*step == 0) return -1;

return 0;

}

来源于svn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值