生成巨大列表的随机排列(在Python中)

时间:2015-06-03 09:06:52

标签: python algorithm iterator permutation

我想创建数字[1,2,...,N]的随机排列,其中N是一个很大的数字。因此,我不想将排列的所有元素存储在内存中,而是迭代我特定排列的元素,而不将以前的值保存在内存中。

知道如何在Python中做到这一点吗?

2 个答案:

答案 0 :(得分:6)

一种可能性是使用加密。由于加密是可逆的,即一对一,对于给定的密钥,您将获得加密的相同数字,但顺序不同。

你需要一个块大小,其块大小足以包含你的最大N.在ECB模式下使用DES,N = 2 ^ 64 - 1.在ECB模式下使用AES,N = 2 ^ 128 - 1.其他大小,使用Hasty Pudding cipher,它具有可变的块大小,或者编写自己的简单Feistel cipher。我假设您只需要一个随机播放,而不是加密安全的随机播放。

如果输出大于N,则只需重新加密直到小于N,1对1属性可确保大数字链也是唯一的。

无需将整个阵列存储在内存中,每个号码都可以根据需要进行加密。只需要密钥和密码算法。一个轻微的复杂因素是块密码在[0 ... N-1]上工作;你可能需要一些额外的代码来处理极端事件。

答案 1 :(得分:0)

这是一个通用问题,而不是特定于Python的问题。在大多数语言中,即使使用迭代器来使用结构,整个结构也会保存在内存中。因此,迭代器主要用作“功能”工具而不是“内存优化”工具。

在python中,由于具有非常大的结构(字典等),很多人最终会使用大量内存。但是,程序的所有变量对象都将以任何方式存储在内存中。唯一的解决方案是数据的序列化(保存在文件系统,数据库等中)。

因此,在您的情况下,您可以创建一个自定义函数来创建排列列表。但是,不是将排列的每个元素添加到列表中,而是将元素保存在文件中(或者在具有相应结构的数据库中)。然后,您将能够从文件(或数据库)逐个检索每个排列,而无需将整个列表放在内存中。

但是,如前所述,您必须始终知道您目前处于哪种排列状态。为了避免从数据库中检索所有创建的排列(这将产生相同的瓶颈),您可以为每个位置保留一个索引,该索引包含在先前生成的排列中使用的符号(并创建添加符号和预定义序列的排列)