0

range(start, stop, step)在我实际调用它之前,如何计算调用会产生的元素数量。

上下文是我正在实现对对象的切片索引

def __init__(self, impl_object):
   self.impl=impl_object # the object that actually holds (or generates) an array of values
def __getitem__(self, key):
    if isinstance(key, slice):
         (start,stop,step)=key.indices( self.impl.numValues() )
         # It would be nice to know how many items I'm dealing with
         # here
    ...snip...

我已经说服自己step>0
len(range(start,stop,step))==(start-stop+step-1)/step

但我不知道如何将其概括为负面步骤。

编辑:我要求(强烈希望)解决方案需要O(1)时间。

4

3 回答 3

4

最简单的方法是

len(xrange(start, stop, step))

xrange.__len__计算它会的元素数yield,而不在内存中构造范围。

于 2013-02-07T15:33:37.710 回答
2

如果您的start, stop, 和与特定于实现的限制step一致(例如 CPython 2.x要求它们是“短”Python 整数),您可以通过调用来获取将包含的值的数量:xrangerange(start, stop, step)

len(xrange(start, stop, step))

在后台,xrange()调用返回一个xrange 对象

XRange 对象的行为很少:它们只支持索引、迭代和 len() 函数。

len()调用是O(1),因为xrange类型实现了根据__len__传递的参数计算的方法,len()发现传递给它的对象实现了__len__,调用它来获取长度。

如果您的startstopstep可能无法与 一起使用xrange(),这里有一个函数(归功于在Hacker News 讨论的帮助下使用 xrange 实现的博客文章):

def len_range(start, stop, step):
    return max(0, (stop - start) // step + bool((stop - start) % step))
于 2013-10-18T01:28:01.137 回答
0

尝试使用 abs(step) 而不是 step。

于 2013-02-07T15:36:43.443 回答