【问题标题】:Python: Alternative for a generator of HUGE listPython:巨大列表生成器的替代方案
【发布时间】:2020-08-17 02:17:08
【问题描述】:

对于我正在编写的包,我需要随机顺序的 0 到 2**33 之间的唯一数字。最初,我尝试使用如下生成器:

def randomnumber(NUM):
    List = [i for i in range(NUM)]
    List.shuffle()
    index = 0
    while index < NUM:
          index += 1
          yield List[index-1]

但在我的例子中 NUM 是 2**33,这个代码是不可能的。我尝试将所有数字从 bash 写入文本文件,发现文件大小为 93.6 GB(这真的很大,远远超过我的 RAM)。然后我使用terashuf 改组文件的内容,并使用linecache 读取文件的每一行。

另外,我正在使用多处理模块(尤其是apply_async)并且确实需要将此生成器对象作为参数传递。但是 python 给出了一个错误,指出它不能在池进程中使用生成器对象。我经历了几个关于 SO 的问题,其中一个答案是从生成器中为少数数字创建这些数字的列表,并将它们作为参数传递给并行运行的函数,但这也不起作用。

所以我的问题是有什么方法可以让我们创建一个生成器来完成预期的工作(给出 0 到 2**33 之间的随机唯一数字)或其他一些我不想要的方法来做到这一点一次又一次地洗牌文件的内容(需要相当多的时间)

【问题讨论】:

标签: python random multiprocessing generator


【解决方案1】:

据我了解,您的代码的要点是在0NUM 之间生成一个随机整数。在你的情况下,NUM 将是 2**33

以下代码可以做到这一点,您可以毫无问题地更改NUM

import math
import random


def generate_random(num):
    yield random.randint(0, num) 

#setting seed to get consistent results
random.seed(0)

# Now, let's use this simple function to generate
# 5 different random number between `0` and `2**33`:
NUM = math.pow(2, 33)
for i in range(10):
    print(next(generate_random(NUM)))

# This would print these five numbers
# 7921731533
# 1806341205
# 6490875490
# 6341935620
# 3900315155

【讨论】:

  • 我需要一个生成 0 到 NUM 之间唯一随机数的代码。你没有完全给出唯一的数字吗?
  • 从技术上讲,生成的数字不是唯一的。但根据伪随机生成器的机制以及数量的多少,它们会有些独特。
  • 这个问题和 OP 的代码似乎表明他想对所有数字的列表进行洗牌,并以随机顺序将每个数字恰好一次。
  • @ThierryLathuille,是的,但是对2^33 大小的列表进行洗牌是非常昂贵的计算方式。所以,我稍微调整了这个问题。我的代码在0NUM 的范围内生成任意数量的不那么独特随机数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
相关资源
最近更新 更多