如何洗牌python无限生成器

如何洗牌python无限生成器,python,iterator,itertools,Python,Iterator,Itertools,我有一个对象,我把它做成一个生成器: class obj(object): def __init__(): pass def __iter__(): a = list(range(10)) shuffle(a) for i in range(len(a)): yield a[i] ..... 可以看出,在创建生成器时有一个随机操作。当我使用itertools.cycl

我有一个对象,我把它做成一个生成器:

class obj(object):
     def __init__():
         pass
     def __iter__():
         a = list(range(10))
         shuffle(a)
         for i in range(len(a)):
             yield a[i]
     .....

可以看出,在创建生成器时有一个随机操作。当我使用
itertools.cycle
时,这个生成器可以无限工作,但是除了第一次之外,不会执行任何洗牌操作。如何创建一个行为类似于itertools.cycle的无限生成器,但仍然可以实现每个循环的洗牌?

首先:不要调用生成器,因为它是为使对象实例可写而保留的(不需要调用特定方法)

为了生成一个无限的值列表,您实际上不需要洗牌。而是每次从列表中随机选取一个值。如果要防止在上一次相同拾取后过早拾取相同的值,请添加逻辑,尽管控制得越多,随机性就越小

import random

class obj(object):
     def __init__(self):
         pass
     def items(self):  # Generator
         a = list(range(10))
         while True:
             yield random.choice(a)
如果您的列表
a
实际上只是一个从0到9(包括)的序列,那么请执行以下操作:

     def items(self):  # Generator
         while True:
             yield random.randint(0, 10)
如果确实希望在重新启动之前生成所有列表值,请注意,第一批的最后一次拾取可能与第二批的第一次拾取相同。不管怎样,这看起来是这样的:

     def items(self):  # Generator
         a = list(range(10))
         while True:
             shuffle(a)
             yield from a

第一:不要调用生成器
\uuuuu iter\uuuu
,因为这是为使对象实例可重用而保留的(不需要调用特定方法)

为了生成一个无限的值列表,您实际上不需要洗牌。而是每次从列表中随机选取一个值。如果要防止在上一次相同拾取后过早拾取相同的值,请添加逻辑,尽管控制得越多,随机性就越小

import random

class obj(object):
     def __init__(self):
         pass
     def items(self):  # Generator
         a = list(range(10))
         while True:
             yield random.choice(a)
如果您的列表
a
实际上只是一个从0到9(包括)的序列,那么请执行以下操作:

     def items(self):  # Generator
         while True:
             yield random.randint(0, 10)
如果确实希望在重新启动之前生成所有列表值,请注意,第一批的最后一次拾取可能与第二批的第一次拾取相同。不管怎样,这看起来是这样的:

     def items(self):  # Generator
         a = list(range(10))
         while True:
             shuffle(a)
             yield from a

执行
def\uu next\uu
。你在洗什么?在
\uuu iter\uuu
中返回什么?@trincot抱歉,我可能误解了生成器和迭代器。我修改了问题。@trincot抱歉,我可能误解了带迭代器的生成器。我修改了这个问题。你为什么要多次洗牌?是否因为您希望有一个概率多次返回相同的列表值,而其他一些则从未返回过?当您想要定义生成器(yield)时,不要将其命名为
\uuuu iter\uuuu
,而是给它一个普通的名称<代码>\uuuu iter\uuuuu用于使类实例可移植。是的,但您肯定希望生成所有已洗牌的值,并且只有在提供完整列表后,才能再次洗牌。在从列表中选择每个值之前将其洗牌是毫无意义的。实现
def\uuu next\uu
。你在洗什么?在
\uuu iter\uuu
中返回什么?@trincot抱歉,我可能误解了生成器和迭代器。我修改了问题。@trincot抱歉,我可能误解了带迭代器的生成器。我修改了这个问题。你为什么要多次洗牌?是否因为您希望有一个概率多次返回相同的列表值,而其他一些则从未返回过?当您想要定义生成器(yield)时,不要将其命名为
\uuuu iter\uuuu
,而是给它一个普通的名称<代码>\uuuu iter\uuuuu用于使类实例可移植。是的,但您肯定希望生成所有已洗牌的值,并且只有在提供完整列表后,才能再次洗牌。在每个人从列表中选择一个值之前洗牌是毫无意义的。我认为最后一个解决方案可能是询问者所说的“每个周期实现洗牌”琐事:第三个解决方案是俄罗斯方块中使用的洗牌。它不像纯随机的。choice()那样随机,因为它允许你计算牌数,这样你猜测下一张牌的机会比chance好,但它的好处是,它保证你永远不会在没有看到任何特定的牌的情况下走太久。我想最后一个解决方案可能就是询问者所说的“每个周期执行洗牌”琐事:第三个解决方案是俄罗斯方块中使用的洗牌。与纯随机的.choice()相比,它的随机性更小,因为它允许您进行卡片计数,因此您猜测下一个磁贴的机会比chance更好,但它的好处是,它保证您不会在没有看到任何特定磁贴的情况下走得太久。