Python 如何创建包含另一个生成器的前N个值的生成器

Python 如何创建包含另一个生成器的前N个值的生成器,python,Python,我有一个132000个正态分布值的数组,它受生成器create\u generator()的约束。这将创建一个表示132e+3*(132e+3-1)/2=8.71e+9行和3列的数组的生成器。我想提取列3中具有前N个最高值的行。所以87亿行。。。我尝试使用heapq.nlargest,但由于生成器已转换为列表,因此这需要花费太长时间。因此,我想知道是否有可能在不将生成器转换为列表的情况下提取前N个值。或者,是否可以配置create_generator(),以便以排序方式动态创建g x = np.

我有一个132000个正态分布值的数组,它受生成器
create\u generator()
的约束。这将创建一个表示132e+3*(132e+3-1)/2=8.71e+9行和3列的数组的生成器。我想提取列3中具有前N个最高值的行。所以87亿行。。。我尝试使用
heapq.nlargest
,但由于生成器已转换为列表,因此这需要花费太长时间。因此,我想知道是否有可能在不将生成器转换为列表的情况下提取前N个值。或者,是否可以配置
create_generator()
,以便以排序方式动态创建
g

x = np.random.normal(0, 1, 132e+3)



def create_generator(x):
    p = x.shape[0]

    for i in range(p):
        for j in range(p):
            if i < j:
                yield i, j, np.mean( [x[i], x[j]] )



g = create_generator(x)


top10 = heapq.nlargest(100000, g, key=lambda x: x[2])

打印(类型(top10))

我尝试了使用
heapq.nlargest()
来获取前N个值(我想要前100e+3个值),但这会返回一个列表。我希望能够创建一个新的生成器。如何在不创建临时列表的情况下从生成器创建另一个生成器?

如果您确实需要避免创建列表,我唯一能想到的其他选项是以下转换:

  • 现在你有:

      One iteration => list of size N
    
  • 相反,你应该:

      N iterations => one variable
    
为避免创建列表,以下操作是循环生成器
n
次。每次抓取最大元素并保存它。以下每次迭代都会找到最大值,不包括前面的迭代:

从数学导入inf
def顶部(n,x):
全局_max=inf
对于范围内的u(n):
cur_max=0
对于创建_生成器(x)中的i、j、elem:
如果cur_max

请注意,这需要使iterable
x
)而不是生成器(
g
)能够从一开始就循环(执行
iter(generator)
返回相同的对象而不是副本)。

如何循环生成的值并保存数组中最大的N个值?(您可以对存储最大值的数组进行排序,以实现更智能的方法来比较/替换最高值)我不确定是否理解。。。但是,如果不运行第二个生成器,则无法创建返回另一个生成器的N个最大值的生成器,直到每次结束。。。这就是为什么第二个生成器被转换为一个列表。@riccardoperaglia是的,您必须运行整个生成器,但我认为如果您至少能够高效地执行此操作,那么您就必须运行整个生成器。但是你是对的,我认为速度不会有多大提高。
heapq.nlargest
返回一个列表,但是你还希望它返回什么呢?在任何情况下,它都会访问每一项,但不会同时将所有结果保存在内存中。为了生成顶部的
N
项(按照您的示例中的顺序),您需要首先拥有这些
N
项。。。为此,您需要迭代生成器并保存大小
N
的列表。。。为了避免保存列表,您需要迭代生成器
N
次。。。这样对你更好吗?
print(type(top10))
<class 'list'>
  One iteration => list of size N
  N iterations => one variable