【问题标题】:how to pick random items from a list while avoiding picking the same item in a row如何从列表中选择随机项目,同时避免连续选择相同的项目
【发布时间】:2016-04-18 14:39:53
【问题描述】:

我想用随机值遍历列表。但是,我希望将已经挑选的物品从列表中删除,以便下次试用,这样我就可以避免连续挑选相同的物品;但之后应该重新添加。

请帮助我在这个简单的例子中展示这一点。 谢谢

import random
    l = [1,2,3,4,5,6,7,8]
    for i in l:
        print random.choice(l)

【问题讨论】:

  • 定义之后的意思。如,程序何时重新运行?或者,仅应在下次尝试时将其删除。
  • 输入值是否保证唯一?您是否期望使用此算法的 toin coss 会产生严格交替的模式?

标签: python list random


【解决方案1】:

两者都适用于非唯一元素列表:

def choice_without_repetition(lst):
    prev = None
    while True:
        i = random.randrange(len(lst))
        if i != prev:
            yield lst[i]
            prev = i

def choice_without_repetition(lst):
    i = 0
    while True:
        i = (i + random.randrange(1, len(lst))) % len(lst)
        yield lst[i]

用法:

lst = [1,2,3,4,5,6,7,8]
for x in choice_without_repetition(lst):
    print x

【讨论】:

    【解决方案2】:

    您可以在遍历列表之前随机打乱列表。然后,在遍历列表后,对其进行排序以使其恢复到原始状态:

    import random
    
    l = [1,2,3,4,5,6,7,8]
    random.shuffle(l)
    for element in l:
        print(element)
    l = sorted(l)
    print(l)
    

    输出

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

    【讨论】:

    • 这不是问题所要求的,因为它特别提到“这样我就可以避免连续选择相同的项目;但应该在之后再次添加”。
    • 这不会连续两次选择同一个项目?
    • 它将从列表中选择项目,而无需两次选择相同的项目。
    【解决方案3】:

    永远画下去,永远不要连续两次选择同一个项目:

    import random
    
    def choice_no_repeat(lst):
        random.shuffle(lst)
        last = lst[0]
        lst.pop(0)
        yield last
        while True:
            random.shuffle(lst)
            last, lst[0] = lst[0], last
            yield last
    
    choice = choice_no_repeat([1, 2, 3, 4, 5, 6, 7, 8])
    for _ in range(10):
        print(next(choice))
    

    示例输出:

    1
    6
    1
    3
    8
    7
    4
    7
    1
    8
    

    【讨论】:

      【解决方案4】:

      编辑:正如评论所解释的,这确实回答了一个不同的问题:如何从 N 数组中提取 M 个不同的数字。

      如果您不介意使用 numpy,它有 np.random.choice 可以满足您的需求:

      从给定的一维数组生成随机样本

      指定replace=False 确保每个元素只绘制一次。如果你绘制所有元素,这将有效地给你一个排列:

      np.random.choice([1,2,3,4,5,6,7,8], 8, replace=False)
      

      【讨论】:

      • 此答案将从列表中选择项目,而无需两次选择相同的项目。但是,这不是问题所要求的,因为它特别提到“这样我就可以避免连续选择相同的项目;但应该在之后再次添加”。
      猜你喜欢
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 2010-09-23
      相关资源
      最近更新 更多