【问题标题】:How to generate random numbers from a list, without repeating the last one? [closed]如何从列表中生成随机数,而不重复最后一个? [关闭]
【发布时间】:2020-07-09 16:50:45
【问题描述】:

我有一个数字列表l = [0,1,2,3,4,5,6,7,8,9],我想从中选择随机数,而无需重复最后选择的数字。

因此,如果我生成一个随机数序列,则永远不应该连续选择两次。

我使用random.choice() 方法从此列表中选择一个随机数。如果我第一次得到4,则在第二次迭代时无法再次选择它,但在第三次迭代时将再次可用。

我该怎么做? Python中是否有任何可用的包以这种方式提供随机数?

【问题讨论】:

  • 这能回答你的问题吗? Non-repetitive random number in numpy,如果没有请创建一个complete and reproducible example
  • 不,因为它提供了一个唯一随机整数的列表,而我每次迭代都需要唯一的随机整数。
  • 为什么不在进入循环之前生成随机数呢?如果不是,您可以使用 np.shuffle 并取前 2 个值。
  • 随机打乱数字列表。然后,您可以从随机列表中一次取出一个。
  • 你不会找到一个库,因为它非常具体,我怀疑有人会实现它。但是,您可以轻松创建自己的函数!甚至发布给其他人使用...

标签: python python-3.x random


【解决方案1】:

如果你随机排列列表:

import random

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(a)
print(a)

结果:

[7, 9, 0, 5, 1, 2, 4, 8, 6, 3]

此外,如果您不想修改原始列表,您可以创建一个索引列表并将其打乱:

index = list(range(len(a)))
random.shuffle(index)

for i in index:
    print(a[i])

【讨论】:

  • 它有效,但是为了只提取一个值而对整个列表进行洗牌是非常低效的。
  • 没错,既然问题已经澄清,唯一合理的解决方案就是与之前绘制的样本进行比较——我在这里推荐你的答案:)
【解决方案2】:

您可以创建一个生成器来生成它们:

import random

def random_without_pairs(data):
    values = set(data)
    previous = None
    while True:
        new = random.sample(values, 1)[0]
        yield new
        values.remove(new)
        if previous is not None:
            values.add(previous)
        previous = new

注意使用random.sample(values, 1) 从集合中生成一个值的列表,因为random.choice 只能用于序列。

你可以这样使用它:

l = [0,1,2,3]
r = random_without_pairs(l)  # create the generator that will generate values from l
for i in range(10):
    print(next(r))

2
3
2
3
1
3
0
2
0
3

如果你想从你的列表中创建一个没有对的 n 个随机值的列表,你可以使用这个小辅助函数:

def n_random_without_pairs(data, n):
    r = random_without_pairs(data)
    return [next(r) for _ in range(n)]

print(n_random_without_pairs(l, 10))

#[1, 3, 2, 3, 2, 3, 0, 1, 3, 1]

【讨论】:

    【解决方案3】:

    好的,感谢@albusSimba 和@Tom Karzes,我得到了解决方案

    import random 
    
    l = [0,1,2,3]
    prev = [0]
    for i in range(20):
        random.shuffle(l)
        if prev[i]==l[0]:
            a = l[1]
        else:
            a =l[0]
        prev.append(a)
        print(a)  
    

    【讨论】:

      【解决方案4】:

      您可以使用while 循环继续从池中抽取,直到它与之前的选择不同:

      import random
      
      def draw(l):
          previous = object()
          while True:
              pick = random.choice(l)
              if pick != previous:
                  previous = pick
                  yield pick
      

      这样下面的代码将永远成功:

      previous = object()
      picks = draw(l)
      for i in range(10000):
          pick = next(picks)
          assert pick != previous
          previous = pick
      

      【讨论】:

        【解决方案5】:

        您可以使用最后选择的值来屏蔽您选择的数组。

        import numpy as np
        
        # array to choose from 
        a = np.arange(10)
        
        #outputs
        picks = []
        
        # initialise first value
        temp=None
        
        for d in range(50):
        
            # choose from the value of array without the one chosen in the last iteration.
            temp = np.random.choice(a[a!=temp])
        
            picks.append(a[temp])
        

        【讨论】:

          【解决方案6】:

          random.shuffle() 本来是最好的方法,但是由于您想包含除最后一项之外的所有项目,因此您可以从以下内容开始。

          l = [0,1,2,3,4,5,6,7,8,9]
          ans = random.choice(l)
          print(ans)
          for i in range(10): # if you need infinite loop you can change this to while true:
              l2 = [x for x in l if x!=ans]
              ans = random.choice(l2)
              print(ans)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-07-02
            • 2019-10-20
            • 2022-06-24
            • 1970-01-01
            • 2014-03-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多