Python 中是否有 `sample` 的生成器版本?

Is there a generator version of `sample` in Python?

NetLogo 认为它的一个重要特征是它以伪随机顺序从代理集中激活代理。如果想在 Python 中做类似的事情,可以执行以下操作。

from random import sample
for agent in sample(agentset, len(agentset)): 
    < do something with agent >

我相信那会很好。问题是 sample returns 一个列表。如果 agentset 很大,则实际上是在复制它。 (我不想使用 shufflepop,因为它们会修改原始代理集。)

理想情况下,我想要一个 sample 的版本,它充当生成器并在请求时提供 yields 值。有这样的功能吗?如果没有,是否想过如何编写一个——既不修改原始集也不复制它?

谢谢。

sample 的基础算法需要与样本大小成比例的内存。 (一种算法是拒绝抽样,另一种是部分洗牌。)两者都不能满足您的要求。

您要查找的内容需要不同的技术,例如 format-preserving encryption。保留格式的密码本质上是从 [0, n) 到 [0, n)(或等效地,从任何有限集到自身)的键控双射。使用保留格式的加密,您的生成器看起来像 (pseudocode)

def shuffle_generator(sequence):
    key = get_random_key()
    cipher = FormatPreservingCipher(key, len(sequence))
    for i in range(len(sequence)):
        yield sequence[cipher.encrypt(i)]

这会比传统的洗牌慢很多,但它会实现您规定的目标。

我不知道 Python 有任何良好的格式保留加密库。 (pyffx 存在,但测试表明 either it's terrible, or it has severe limitations that aren't clearly documented。无论哪种方式,它似乎都不适用于此。)你最好的选择可能是包装一个用不同语言实现的库。