如何在实际调用之前计算调用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)
时间。
答案 0 :(得分:4)
最简单的方法是
len(xrange(start, stop, step))
xrange.__len__
计算yield
元素的数量,而不在内存中构建范围。
答案 1 :(得分:2)
如果您的start
,stop
和step
与the implementation-specific limitations for xrange
一致(例如CPython 2. x 要求他们' “短”Python整数'),您可以通过调用获得range(start, stop, step)
将包含的值的数量:
len(xrange(start, stop, step))
在幕后,xrange()
调用会返回xrange object:
XRange对象的行为非常少:它们只支持索引, 迭代和len()函数。
len()
调用是O(1),因为xrange类型使用基于传递的参数的计算实现__len__
方法,并且len()
发现传递给它的对象实现__len__
,并调用它来获取长度。
如果您的start
,stop
和step
可能不适用于xrange()
,则此处为a blog post with an xrange implementation的功能a Hacker News discussion {3}}):
def len_range(start, stop, step):
return max(0, (stop - start) // step + bool((stop - start) % step))
答案 2 :(得分:0)
尝试使用abs(步骤)而不是步骤。