Python: 如何在不创建范围的情况下计算范围的长度?
Python: How to calculate the length of a range without creating the range?
我需要计算一个范围的长度,但最好不要创建范围,(希望会更快并且使用更少的内存。这很重要,因为这个函数会被调用很多次)。长度用于设置扩展切片。
目前我已经尝试过:
int_div = lambda n, d: (n + d // 2) // d
def range_len(start, stop, step):
return int_div(stop - start, step)
但在某些情况下,例如range_len(9, 100, 3) 正确答案是31时它给出30。我觉得这应该很简单,我做错了什么?
它给出 30,因为当您希望它始终四舍五入时,您的整数除法会四舍五入到最接近的整数。我不知道它有多快,但我只是使用 math.ceil 和浮点数除法。
在Python2中,可以使用xrange
。在Python3中,可以使用range
。在两者中,它们 return xrange
/range
对象而不是生成整个列表。
Python 2
return len(xrange(start, stop, step))
Python 3
return len(range(start, stop, step))
来自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.
或 range
中的帮助 Python 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).
创建 xrange
/range
对象比创建关联列表的长度更快且内存效率更高。
使用此方法计算从 0 到 1000000 的范围花费了我的 PC 大约 0.000004291534423828125 秒。
您可以使用这个公式:(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)
我需要计算一个范围的长度,但最好不要创建范围,(希望会更快并且使用更少的内存。这很重要,因为这个函数会被调用很多次)。长度用于设置扩展切片。
目前我已经尝试过:
int_div = lambda n, d: (n + d // 2) // d
def range_len(start, stop, step):
return int_div(stop - start, step)
但在某些情况下,例如range_len(9, 100, 3) 正确答案是31时它给出30。我觉得这应该很简单,我做错了什么?
它给出 30,因为当您希望它始终四舍五入时,您的整数除法会四舍五入到最接近的整数。我不知道它有多快,但我只是使用 math.ceil 和浮点数除法。
在Python2中,可以使用xrange
。在Python3中,可以使用range
。在两者中,它们 return xrange
/range
对象而不是生成整个列表。
Python 2
return len(xrange(start, stop, step))
Python 3
return len(range(start, stop, step))
来自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.
或 range
中的帮助 Python 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).
创建 xrange
/range
对象比创建关联列表的长度更快且内存效率更高。
使用此方法计算从 0 到 1000000 的范围花费了我的 PC 大约 0.000004291534423828125 秒。
您可以使用这个公式:(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)