【问题标题】:Select unique value from list从列表中选择唯一值
【发布时间】:2012-10-22 18:37:13
【问题描述】:

我想要做的是,有一个字符列表,每个字符都是一个过程,然后我想从这个列表中随机选择(或伪随机,没关系),并执行该过程,然后我希望能够再次运行它,而不是获得相同的值,例如,如果我有五个值,我希望能够运行它 5 次,那么我第 6 次运行它,它什么也不返回。代码如下:

from Tkinter import*
from random import randint
Characters=[Percy,Annabeth,Leo,Chuck,Sarah]
Used = []
def callback():
    end = len(Characters)-1
    rando = randint(0,end)
    Characters[rando]
    for i in Characters:
         if Characters[rando] in Used:
            print 'This has already been used'
         else:
            Characters[rando]()
            Used.append(Characters[rando])
            break


game = Tk()
game.geometry('50x50+700+100')
Button1 = Button(game,text = '1',command =lambda:callback() )
Button1.pack(side=LEFT)


game.mainloop() 

我正在努力

callback()

要正常运行,你看到的我都试过了,但我也试过了

if Characters[rando] in Used:
    print 'This has already been used'
else: 
   Characters[rando]
   Used.append(Characters[rando])

在这两种情况下,它都会多次运行相同的程序,例如,“Leo”可能会连续执行 3 次。我花了好几个小时寻找一种方法来做到这一点,但我找不到。

【问题讨论】:

标签: python random python-2.7 unique


【解决方案1】:

首先,我会shuffleCharacters

Characters = [Percy,Annabeth,Leo,Chuck,Sarah]
random.shuffle(Characters)

现在,当您运行回调时,您 pop 会输出一个字符:

def callback():
    try:
       C = Characters.pop()  #popping the last one is more efficient than the first.
    except IndexError:
       return None

    return C()

由于这会破坏Characters,如果需要,您可能需要保留一份副本以进行重置:

 random.shuffle(Characters)
 Characters_save = Characters[:]

 def reset_characters():
     Characters[:] = Characters_save[:]

【讨论】:

  • 你不需要为.pop()指定索引,让它弹出最后一个,因为它是最有效的
  • @JonClements -- 为了提高效率,我将其更改为 .pop(-1),但您是对的。此处无需指定。已更新。
  • shuffle 也在原地,所以返回 None 并且您需要保存 before 改组...
  • @JonClements -- 谢谢。忘记那个了。
  • 我试过了,我得到了错误'C = Characters.pop(0) AttributeError: 'NoneType' object has no attribute 'pop'
【解决方案2】:

完全未经测试 - 但您可以实现一个基本类:

from random import shuffle

class CallNext(object):
    def __init__(self, vals):
        self.vals = vals[:]
        shuffle(self.vals)
        self.iter = iter(self.vals)
    def __call__(self):
        try:
            next(self.iter)()
        except StopIteration as e:
            pass # or do something smarter?

另一种替代捕获StopIteration 的方法是使用:

next(self.iter, lambda: None)()

然后有:

Button1 = Button(game, text='1', command=CallNext(Characters) )

【讨论】:

    猜你喜欢
    • 2012-01-24
    • 2012-03-28
    • 1970-01-01
    • 2016-10-25
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多