Python中的随机迭代

xra*_*alf 25 python random for-loop

当你想在数字列表上按顺序迭代时,你会写:

for i in range(1000):
  # do something with i
Run Code Online (Sandbox Code Playgroud)

但是如果你想随机迭代范围(0..999)中的数字列表呢?需要(在每次迭代中)随机选择在任何先前迭代中未选择的数字,并且需要迭代范围(0..999)中的所有数字.

你知道怎么做(智能)吗?

Nik*_* B. 29

您可以使用random.shuffle(),以及随机播放列表:

import random

r = list(range(1000))
random.shuffle(r)
for i in r:
  # do something with i
Run Code Online (Sandbox Code Playgroud)

顺便说一下,在许多情况下,你for在其他编程语言中使用一系列整数的循环,你可以直接描述你想在Python中迭代的"东西".
例如,如果要使用值i来访问列表的元素,则应该更好地直接对列表进行洗牌:

lst = [1970, 1991, 2012]
random.shuffle(lst)
for x in lst:
  print x
Run Code Online (Sandbox Code Playgroud)

注意:使用时应记住以下警告random.shuffle()(取自文档:

注意,对于相当小的len(x),x的排列总数大于大多数随机数生成器的周期; 这意味着永远不会产生长序列的大多数排列.

  • 此外,Python自动播种其随机数生成器,因此不需要调用`random.seed()`. (3认同)
  • @Greg:实际上我注意到 random.shuffle 修改了操作数,所以我什至不能将它用作表达式:/不过,感谢您的提示,我更改了它。 (2认同)

Ned*_*der 17

人们经常错过模块化的机会.您可以定义一个函数来封装"随机迭代"的想法:

def randomly(seq):
    shuffled = list(seq)
    random.shuffle(shuffled)
    return iter(shuffled)
Run Code Online (Sandbox Code Playgroud)

然后:

for i in randomly(range(1000)):
    #.. we're good to go ..
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么我退回了它.返回列表也应该没问题. (2认同)

Jam*_*ven 17

这是一种以随机顺序迭代列表的不同方法。与使用 shuffle() 的解决方案不同,这不会修改原始列表

lst=['a','b','c','d','e','f']
for value in sorted(lst,key=lambda _: random.random()):
    print value
Run Code Online (Sandbox Code Playgroud)

或者:

for value in random.sample(lst,len(lst)):
    print value
Run Code Online (Sandbox Code Playgroud)

  • 高度被低估的解决方案,如果需要保留原始列表,则不需要创建列表的临时副本进行洗牌 - 并且不需要调用 numpy (尽管 numpy 的排列也是一个不错的解决方案)。+1 (2认同)

lee*_*ewz 6

演示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
Run Code Online (Sandbox Code Playgroud)

您只生成所用的随机数.但老实说,这可能不会节省太多,所以你应该经常使用random.shuffle.

注意:如果选择顶部卡,deck[i] = deck.pop()则不安全,因此移除顶部分两步完成.

  • 这可能是一个最被低估的答案。其他(包括接受的)都将可迭代对象转换为列表并对其进行洗牌。这适用于大多数(简单)情况,但如果您的迭代器(非常)大,则内存效率低下并杀死您的程序。例如,使用其他解决方案不可能处理长列表的笛卡尔积。 (2认同)

小智 6

还有一个功能,random.permutation()numpy这不正是你.你的代码看起来像

from numpy.random import permutation

for i in permutation(1000):
    # do something with i
Run Code Online (Sandbox Code Playgroud)