【发布时间】:2012-03-04 08:58:30
【问题描述】:
当你想按顺序迭代一个数字列表时,你会写:
for i in range(1000):
# do something with i
但是,如果您想随机遍历 (0..999) 范围内的数字列表怎么办?需要(在每次迭代中)随机选择在任何先前迭代中未选择的数字,并且需要迭代范围 (0..999) 中的所有数字。
你知道怎么做吗(聪明)?
【问题讨论】:
当你想按顺序迭代一个数字列表时,你会写:
for i in range(1000):
# do something with i
但是,如果您想随机遍历 (0..999) 范围内的数字列表怎么办?需要(在每次迭代中)随机选择在任何先前迭代中未选择的数字,并且需要迭代范围 (0..999) 中的所有数字。
你知道怎么做吗(聪明)?
【问题讨论】:
这是一种以随机顺序迭代列表的不同方法。与使用 shuffle() 的解决方案不同,这不会修改原始列表
lst=['a','b','c','d','e','f']
for value in sorted(lst,key=lambda _: random.random()):
print value
或:
for value in random.sample(lst,len(lst)):
print value
【讨论】:
您可以使用random.shuffle() 来随机播放列表:
import random
r = list(range(1000))
random.shuffle(r)
for i in r:
# do something with i
顺便说一句,在许多情况下,您会在其他编程语言中对一系列整数使用 for 循环,您可以直接描述要在 Python 中迭代的“事物”。
例如,如果你想使用i 的值来访问列表的元素,你最好直接打乱列表:
lst = [1970, 1991, 2012]
random.shuffle(lst)
for x in lst:
print x
注意:在使用random.shuffle() 时应牢记以下警告(取自docs:
请注意,即使是相当小的 len(x),总 x 的排列大于大多数随机数的周期 发电机;这意味着长序列的大多数排列可以 永远不会生成。
【讨论】:
random.seed()。
numpy 中有一个函数 random.permutation() 可以为您完成此任务。
你的代码看起来像
from numpy.random import permutation
for i in permutation(1000):
# do something with i
【讨论】:
演示 Python 生成器和 Fisher–Yates shuffle。
import random
def shuffled(sequence):
deck = list(sequence)
while len(deck):
i = random.randint(0, len(deck) - 1) # choose random card
card = deck[i] # take the card
deck[i] = deck[-1] # put top card in its place
deck.pop() # remove top card
yield card
您只会生成尽可能多的随机数。但老实说,它可能不会节省多少,所以你通常应该使用random.shuffle。
注意:如果选择顶部卡片,deck[i] = deck.pop() 将不安全,因此移除顶部卡片分两步完成。
【讨论】:
deck = list(sequence)。您可能可以通过懒惰地构建列表而侥幸逃脱,但它与其他人一样是渐近的时间和记忆。此解决方案仅允许您生成所需数量的随机数,而且随机数很便宜。
人们经常错过模块化的机会。你可以定义一个函数来封装“随机迭代”的思想:
def randomly(seq):
shuffled = list(seq)
random.shuffle(shuffled)
return iter(shuffled)
然后:
for i in randomly(range(1000)):
#.. we're good to go ..
【讨论】:
使用 random.shuffle 方法:
itrange = list(range(100))
random.shuffle(itrange)
for i in itrange:
print i
【讨论】:
list(range(100)),因为 range 在 3.x 中返回一个迭代器。