Python randrange()函数是如何工作的?
我一直在想python中的random.randrange()函数是如何返回的 在非二次幂的范围内具有均匀偏置的值(这很容易,因为N位是随机产生的)Python randrange()函数是如何工作的?,python,Python,我一直在想python中的random.randrange()函数是如何返回的 在非二次幂的范围内具有均匀偏置的值(这很容易,因为N位是随机产生的) 提前谢谢 您可以阅读源代码: 文件位置: >>> import random >>> random.__file__ 'C:\\Python27\\lib\\random.pyc' 文件'C:\\Python27\\lib\\random.py': def randrange(self, start, stop
提前谢谢 您可以阅读源代码: 文件位置:
>>> import random
>>> random.__file__
'C:\\Python27\\lib\\random.pyc'
文件'C:\\Python27\\lib\\random.py'
:
def randrange(self, start, stop=None, step=1, int=int, default=None,
maxwidth=1L<<BPF):
"""Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
Do not supply the 'int', 'default', and 'maxwidth' arguments.
"""
# This code is a bit messy to make it fast for the
# common case while still doing adequate error checking.
istart = int(start)
if istart != start:
raise ValueError, "non-integer arg 1 for randrange()"
if stop is default:
if istart > 0:
if istart >= maxwidth:
return self._randbelow(istart)
return int(self.random() * istart)
raise ValueError, "empty range for randrange()"
# stop argument supplied.
istop = int(stop)
if istop != stop:
raise ValueError, "non-integer stop for randrange()"
width = istop - istart
if step == 1 and width > 0:
# Note that
# int(istart + self.random()*width)
# instead would be incorrect. For example, consider istart
# = -2 and istop = 0. Then the guts would be in
# -2.0 to 0.0 exclusive on both ends (ignoring that random()
# might return 0.0), and because int() truncates toward 0, the
# final result would be -1 or 0 (instead of -2 or -1).
# istart + int(self.random()*width)
# would also be incorrect, for a subtler reason: the RHS
# can return a long, and then randrange() would also return
# a long, but we're supposed to return an int (for backward
# compatibility).
if width >= maxwidth:
return int(istart + self._randbelow(width))
return int(istart + int(self.random()*width))
if step == 1:
raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
# Non-unit step argument supplied.
istep = int(step)
if istep != step:
raise ValueError, "non-integer step for randrange()"
if istep > 0:
n = (width + istep - 1) // istep
elif istep < 0:
n = (width + istep + 1) // istep
else:
raise ValueError, "zero step for randrange()"
if n <= 0:
raise ValueError, "empty range for randrange()"
if n >= maxwidth:
return istart + istep*self._randbelow(n)
return istart + istep*int(self.random() * n)
def randrange(self、start、stop=None、step=1、int=int、default=None、,
maxwidth=1L=maxwidth:
返回自我。\u Randdown(istart)
返回int(self.random()*istart)
raise VALUERROR,“randrange()的范围为空”
#提供了停止参数。
istop=int(停止)
如果istop!=停止:
raise VALUERROR,“randrange()的非整数停止”
宽度=istop-istart
如果步长==1且宽度>0:
#注意
#int(istart+self.random()*宽度)
反之则不正确。例如,考虑ISTART。
#=-2,istop=0。那么肠子就在里面了
#-2.0到0.0两端互斥(忽略该随机()
#可能返回0.0),并且由于int()向0截断
#最终结果将是-1或0(而不是-2或-1)。
#istart+int(self.random()*宽度)
#这也是不正确的,因为一个微妙的原因:RHS
#可以返回long,然后randrange()也将返回
#长,但我们应该返回一个int(向后)
#兼容性)。
如果宽度>=最大宽度:
返回整数(istart+self.\u低于(宽度))
返回int(istart+int(self.random()*width))
如果步骤==1:
raise VALUERROR,“randrange()的空范围(%d,%d,%d)”%(istart,istop,width)
#提供了非单位步长参数。
istep=int(步骤)
如果istep!=步骤:
raise VALUERROR,“randrange()的非整数步长”
如果istep>0:
n=(宽度+istep-1)//istep
elif istep<0:
n=(宽度+istep+1)//istep
其他:
raise VALUE ERROR,“randrange()的零阶跃”
如果n=最大宽度:
返回istart+istep*self.\u如下(n)
返回istart+istep*int(self.random()*n)
快速查看源代码后,以下是基本原则:
def randrange(start, stop, step)
width = stop - start
n = (width + step - 1) // step
return start + step * int(random() * n)
好吧,这都是开源的,所以请阅读代码Luke(tm)。我建议你读一下这篇文章,我想用Vincent的答案。他的ans是“甜蜜而简单的”,对不起:)