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
很大,则实际上是在复制它。 (我不想使用 shuffle
或 pop
,因为它们会修改原始代理集。)
理想情况下,我想要一个 sample
的版本,它充当生成器并在请求时提供 yield
s 值。有这样的功能吗?如果没有,是否想过如何编写一个——既不修改原始集也不复制它?
谢谢。
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。无论哪种方式,它似乎都不适用于此。)你最好的选择可能是包装一个用不同语言实现的库。
NetLogo 认为它的一个重要特征是它以伪随机顺序从代理集中激活代理。如果想在 Python 中做类似的事情,可以执行以下操作。
from random import sample
for agent in sample(agentset, len(agentset)):
< do something with agent >
我相信那会很好。问题是 sample
returns 一个列表。如果 agentset
很大,则实际上是在复制它。 (我不想使用 shuffle
或 pop
,因为它们会修改原始代理集。)
理想情况下,我想要一个 sample
的版本,它充当生成器并在请求时提供 yield
s 值。有这样的功能吗?如果没有,是否想过如何编写一个——既不修改原始集也不复制它?
谢谢。
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。无论哪种方式,它似乎都不适用于此。)你最好的选择可能是包装一个用不同语言实现的库。