Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何在不创建范围的情况下计算范围的长度?_Python_List_Python 2.7_Slice - Fatal编程技术网

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)