使用生成器对象字典进行多处理,TypeError:无法pickle“generator”对象

2024-06-12 00:24:33 发布

您现在位置:Python中文网/ 问答频道 /正文

如何使用多处理创建以生成器对象作为值的字典

下面是我的问题的详细情况,使用基本示例:

我有一个很大的列表字典,通过它,我可以使用concurrent.futures中的ProcessPoolExecutor应用函数来计算字典值。(注意,我使用的是ProcessPoolExecutor,而不是线程——这里没有GIL争用。)

以下是列表字典示例:

example_dict1 = {'key1':[367, 30, 847, 482, 887, 654, 347, 504, 413, 821],
    'key2':[754, 915, 622, 149, 279, 192, 312, 203, 742, 846], 
    'key3':[586, 521, 470, 476, 693, 426, 746, 733, 528, 565]}

这是一个小例子——实际上,它是一个包含数百万个键和包含数千个元素的列表的大型词典

最初,我使用一个附加到空列表的函数来处理这些值列表,例如

import concurrent

def manipulate_values(dict_items):
    k, v = dict_items
    return_values = []   ## empty list
    for i in v :
        new_value = i ** 2 - 13      ## compute something; just an example
        return_values.append(new_value)  ## append to list
    return k, return_values

with concurrent.futures.ProcessPoolExecutor() as executor:
        new_dict = dict(executor.map(manipulate_values, example_dict1.items()))

但是,生成的字典列表return_values对于内存来说太大。因为我无法在内存中保存这些大量列表,所以我决定尝试生成器函数,即创建键和生成器对象的字典:

## generator function
def compute_values(v):
    for i in v:
        yield i ** 2 - 13   ## using example above; could be any function call 

def manipulate_values_with_generator(dict_items):
    keys, value_lists = dict_items
    return keys, compute_values(value_lists)

with concurrent.futures.ProcessPoolExecutor() as executor:
        new_dict = dict(executor.map(manipulate_values_with_generator, example_dict1.items()))

在实际的“大数据”字典中,这将导致酸洗错误:

TypeError: cannot pickle 'generator' object

关于这个主题还有其他问题,但我不确定如何解决我的问题——像dillpathos这样的包不能与生成器一起工作

Can't pickle <type 'instancemethod'> when using multiprocessing Pool.map()

Can't pickle Pyparsing expression with setParseAction() method. Needed for multiprocessing

当然,也许还有另一种方法可以解决我的基本问题,那就是在内存或生成器中的一个大型列表字典上进行多处理。也许另一种数据结构在这里会有用


Tags: 列表newreturn字典valueexamplewithitems