繁体   English   中英

随机列表选择:如何确保同一项目不会连续重复两次,一个接一个?

[英]random list choice: How do I make sure the same item isn't ever repeated twice in a row, one after the other?

import random

welcomes = ["Hello","Hi","What's up","YO", "Piss off"]

chosen = random.choice(welcomes)

print("You have entered the welcome cave ----- {} -----".format(chosen))

我如何确保Hello不会连续重复两次? 如果它们稍后再次重复也没关系,只是不要紧接着。

使用random.sample而不是random.choice 查找在线演示

import random

welcomes = ["Hello","Hi","What's up","YO", "Piss off"]

chosen = random.sample(welcomes,2)

for item in chosen:
  print("You have entered the welcome cave ----- {} -----".format(item))

如果您想要生成具有该属性的非常长的问候流:没有连续的问候是相同的(在线演示: 最后版本 ):

import random

def random_hello():
    welcomes = ["Hello", "Hi", "What's up", "YO", "Piss off"]
    last_hello = None
    while 1:
        random.shuffle(welcomes)
        if welcomes[0] == last_hello:
            continue
        for item in welcomes:
            yield item
        last_hello = welcomes[-1]


hellower = iter(random_hello())
for _ in range(1000):
    print(next(hellower))

或者当您担心确定性时间时,交换元素(使用1st):

if welcomes[0] == last_hello:
    welcomes[0], welcomes[1] = welcomes[1], welcomes[0]

或随机:

if welcomes[0] == last_hello:
    swap_with = random.randrange(1, len(welcomes))
    welcomes[0], welcomes[swap_with] = welcomes[swap_with], welcomes[0]

使用random.sample和其他建议的答案只有在你知道你只需要一定数量的项目时才有用,比如2。确保随机性和不重复的最好方法是使用random.shuffle

import random
welcomes = ["Hello","Hi","What's up","YO", "Piss off"]
random.shuffle(welcomes)

这样就可以在列表中自动填充,然后你可以开始从列表中pop项目,直到它完成:

while len(welcomes)>0:
    print("You have entered the welcome cave ----- {} -----".format(welcomes.pop())

这适用于任何长度的列表,您可以使用此过程直到整个列表完成。 如果你想让它永远保持下去,而不是直到列表结束,你还可以在整个过程中添加另一个循环。

你可以通过命中和错过方法来做到这一点:

import random

class RandomChoiceNoImmediateRepeat(object):
    def __init__(self, lst):
        self.lst = lst
        self.last = None
    def choice(self):
        if self.last is None:
            self.last = random.choice(self.lst)
            return self.last
        else:
            nxt = random.choice(self.lst)
            # make a new choice as long as it's equal to the last.
            while nxt == self.last:   
                nxt = random.choice(self.lst)
            # Replace the last and return the choice
            self.last = nxt
            return nxt

一个chould用random.choices和权重(需要python-3.6)来改进它,但这种方法适用于所有python版本:

>>> welcomes = ["Hello","Hi","What's up","YO", "Piss off"]
>>> gen = RandomChoiceNoImmediateRepeat(welcomes)
>>> gen.choice()
'YO'

或者如果你不喜欢命中和未命中,你也可以在0和列表长度之间绘制一个随机索引 - 2如果它等于或高于前一个,则加1。 这确保不会发生重复,只需要一次random调用即可获得下一个选择:

import random

class RandomChoiceNoImmediateRepeat(object):
    def __init__(self, lst):
        self.lst = lst
        self.lastidx = None

    def choice(self):
        if self.lastidx is None:
            nxtidx = random.randrange(0, len(self.lst))
        else:
            nxtidx = random.randrange(0, len(self.lst)-1)
            if nxtidx >= self.lastidx:
                nxtidx += 1
        self.lastidx = nxtidx
        return self.lst[nxtidx]

我的看法:我们创建两个相同的列表。 在循环中,我们从一个列表中弹出一个值,如果该列表的长度小于原始列表 - 1,我们将列表重置为其原始状态:

import random

origin = ["Hello","Hi","What's up","YO", "Piss off"]
welcomes = origin.copy()

for i in range(5):
    if len(welcomes) < len(origin) - 1:
        welcomes = origin.copy()
    random.shuffle(welcomes) # shuffle
    chosen = welcomes.pop() # pop one value
    print("You have entered the welcome cave ----- {} -----".format(chosen))

例如输出有5个循环:

You have entered the welcome cave ----- Piss off -----
You have entered the welcome cave ----- YO -----
You have entered the welcome cave ----- Piss off -----
You have entered the welcome cave ----- YO -----
You have entered the welcome cave ----- What's up -----

[a = list.consumableList]而不是只是列表放在= output

(将括号中的小写列表替换为您的列表名称)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM