我想知道哪个shuffle()
和choice()
效率更高。例如,我有一个N元素列表long_list
并需要列表中的随机项,是否更快做:
shuffle(long_list)
return long_list[0]
要么
return choice(long_list)
random.choice()
总是会更快,因为它在恒定时间内查找O(1)
random.shuffle()
需要迭代整个序列来执行shuffle,这将是O(n),然后你的查找是恒定时间O(1)
使用random.choice
肯定会更快。
你可以通过查看at the code轻松搞清楚这一点。 (cpython中的random
模块主要在Python中实现,只有低级随机数生成在C中。)以下是相关部分,它们恰好相邻:
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
try:
i = self._randbelow(len(seq))
except ValueError:
raise IndexError('Cannot choose from an empty sequence') from None
return seq[i]
def shuffle(self, x, random=None):
"""Shuffle list x in place, and return None.
Optional argument random is a 0-argument function returning a
random float in [0.0, 1.0); if it is the default None, the
standard random.random will be used.
"""
if random is None:
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1)
x[i], x[j] = x[j], x[i]
else:
_int = int
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = _int(random() * (i+1))
x[i], x[j] = x[j], x[i]
choice
方法只生成一个随机数,并使用它来索引它给出的序列。另一方面,shuffle
方法在序列的长度上循环,并在其前进时交换元素。所以choice
将花费O(1)时间,而shuffle
花费O(N)时间。
在大多数情况下,如果您只需要一个值,则需要使用random.choice
。如果您想要几个非重复选择,请使用random.sample
。只有当你要使用所有的值时才使用random.shuffle
。请注意,即使您确实希望选择多个项目,如果您希望可以多次选择同一项目,仍应使用random.choice
。采样和随机播放将永远不会重复项目(除非项目在输入列表中重复)。