Python:如何在不创建范围的情况下计算范围的长度?

Ree*_*Oei 5 python list slice python-2.7

我需要计算一个范围的长度,但理想情况下不需要创建范围,(希望会更快并且使用更少的内存.这很重要,因为这个函数会被调用很多).长度用于设置扩展切片.

现在我尝试过:

int_div = lambda n, d: (n + d // 2) // d

def range_len(start, stop, step):
    return int_div(stop - start, step)
Run Code Online (Sandbox Code Playgroud)

但是在某些情况下,例如range_len(9,100,3),当正确的答案是31时,它会给出30分.我觉得这应该很简单,我做错了什么?

DTi*_*ing 7

你可以使用这个公式: (end - start - 1) // step + 1

def calc_length(start, end, step):
    return (end - start - 1) // step + 1

for i in range(start, end):
    calculated = calc_length(start, i, step)
    empirical = len(range(start, i, step))

    assert calculated == empirical, "{} {}".format(calculated, empirical)
Run Code Online (Sandbox Code Playgroud)

  • @Kytuzian:它失败了一个消极的步骤,例如,`range(10,0,-1)`.您可以使用[此实现代替](https://github.com/zed/lrange/blob/7bac49b3673ac632ae89c571d745c547854a54c3/lrange.py#L121-L134) (3认同)

Muh*_*suf 5

在 Python 2 中,您可以使用xrange. 在 Python 3 中,您可以使用range. 在两者中,它们都返回xrange/range对象而不是生成整个列表。

蟒蛇 2

return len(xrange(start, stop, step))
Run Code Online (Sandbox Code Playgroud)

蟒蛇 3

return len(range(start, stop, step))
Run Code Online (Sandbox Code Playgroud)

xrange帮助(在 Python 2 解释器类型中help(xrange)):

class xrange(object)  
|  xrange([start,] stop[, step]) -> xrange object  
|  
|  Like range(), but instead of returning a list, returns an object that   
| generates the numbers in the range on demand.  For looping, this is  
|  slightly faster than range() and more memory efficient.
Run Code Online (Sandbox Code Playgroud)

或者rangePython 3 中的帮助:

class range(object)  
 |  range(stop) -> range object  
 |  range(start, stop[, step]) -> range object  
 |  
 |  Return an object that produces a sequence of integers from start (inclusive)  
 |  to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.  
 |  start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.  
 |  These are exactly the valid indices for a list of 4 elements.  
 |  When step is given, it specifies the increment (or decrement).
Run Code Online (Sandbox Code Playgroud)

创建xrange/range对象比创建关联列表的长度更快,内存效率更高。

使用这种方法计算从 0 到 1000000 的范围需要我的 PC 大约 0.000004291534423828125 秒。