Python:如何在不创建范围的情况下计算范围的长度?
我需要计算一个范围的长度,但理想情况下不创建范围(希望速度更快,占用内存更少。这很重要,因为这个函数会被大量调用)。长度用于设置扩展切片 现在我试过:Python:如何在不创建范围的情况下计算范围的长度?,python,list,python-2.7,slice,Python,List,Python 2.7,Slice,我需要计算一个范围的长度,但理想情况下不创建范围(希望速度更快,占用内存更少。这很重要,因为这个函数会被大量调用)。长度用于设置扩展切片 现在我试过: int_div = lambda n, d: (n + d // 2) // d def range_len(start, stop, step): return int_div(stop - start, step) 但在某些情况下,如range_len(9100,3),当正确答案为31时,它给出30。我觉得这应该很简单,我做错了什
int_div = lambda n, d: (n + d // 2) // d
def range_len(start, stop, step):
return int_div(stop - start, step)
但在某些情况下,如range_len(9100,3),当正确答案为31时,它给出30。我觉得这应该很简单,我做错了什么?它给出了30,因为您的整数除法是四舍五入到最接近的整数,而您希望它总是四舍五入。我不知道它有多快,但我只使用math.ceil和float除法。在Python2中,可以使用
xrange
。在Python3中,可以使用range
。在这两种情况下,它们都返回xrange
/range
对象,而不是生成整个列表
Python 2
return len(xrange(start, stop, step))
Python 3
return len(range(start, stop, step))
从xrange
帮助(在Python 2解释器中键入help(xrange)
):
或者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的范围花费了我的电脑大约0.000004291534423828125秒。您可以使用此公式:(end-start-1)//步骤+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)
@抱歉,我不明白你的意思。你是说我应该做:范围(开始、停止、步骤)*步骤-1,如果步骤大于0?(我想你不是,因为这是错误的,但这就是我所理解的)为什么不选择xrange?这有什么区别呢?不管它值多少钱,python3中的range
实现了一个\uuu_u_u
,它只计算术语的数量(正是您在这里所做的)。因此,在python3的range
上调用len
是O(1)。@NightShadeQueen我正在使用Python2.7,但谢谢。@NightShadeQueen:这很有趣,我认为python3的range
与Python2的xrange
完全相同。我已经想到了这一点,但我认为其他解决方案会更快。结果发现它们都非常相似(除了射程,这要慢得多)。Python 2.7在这里###清晰的解决方案#####谢谢,这是可行的,除了range()之外的所有解决方案似乎都具有相似的速度,它们都可以工作。谢谢,这是可行的,所有解决方案除了range()之外似乎都具有相似的速度,它们都可以工作,但我认为这是最简单的。@Kytuzian:它失败于一个负步骤,例如,range(10,0,-1)
。你可以用@J.F.Sebastian谢谢。我的程序中没有消极的步骤,但我会把它保存起来以防万一。
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)