Python中无重复的多处理迭代
在python中,我有一个很大的数字列表(约5亿项),其中包含一些重复项,例如:Python中无重复的多处理迭代,python,iteration,unique,python-multiprocessing,Python,Iteration,Unique,Python Multiprocessing,在python中,我有一个很大的数字列表(约5亿项),其中包含一些重复项,例如: [1,1,2,2,3,4,5,6,6] 我想对这些数字应用一个函数来创建一个字典,由数字输入,给出函数结果。因此,如果函数只是(比如)lambda x:x*10,我想要一个类似于: {1:10, 2:20, 3:30, 4:40, 5:50, 6:60} 问题是,我想使用Python多处理模块来实现这一点(我不关心函数的运行顺序),我也不想事先让数字列表唯一:我更喜欢在迭代数字时检查是否有重复,如果是的话,不将
[1,1,2,2,3,4,5,6,6]
我想对这些数字应用一个函数来创建一个字典,由数字输入,给出函数结果。因此,如果函数只是(比如)lambda x:x*10
,我想要一个类似于:
{1:10, 2:20, 3:30, 4:40, 5:50, 6:60}
问题是,我想使用Python多处理模块来实现这一点(我不关心函数的运行顺序),我也不想事先让数字列表唯一:我更喜欢在迭代数字时检查是否有重复,如果是的话,不将计算添加到多处理池或队列
因此,我是否应该为此使用multiprocessing.Pool.imap_unordered之类的工具,并检查以前访问过的迭代器,例如:
import multiprocessing
import itertools
import time
def f(x):
print(x)
time.sleep(0.1)
return x, x*10.0
input = [1, 1, 2, 2, 3, 4, 5, 6, 6]
result = {}
def unique_everseen(iterable):
for element in iterable:
if element not in result:
result[element] = None # Mark this result as being processed
yield element
with multiprocessing.Pool(processes=2) as pool:
for k, v in pool.imap_unordered(f, unique_everseen(input)):
result[k]=v
我问,因为使用
结果
字典来检查我们以前是否访问过这个值似乎有点不方便(我这样做是为了避免创建一个单独的5亿项集来检查它们是否是重复项)。有没有一种更像python的方法来实现这一点,比如将项目添加到队列或其他什么?我以前很少使用多处理,所以可能我做得不对,例如,让自己接受竞争条件?首先将列表转换为一个集合,然后在集合上迭代?input=set(input)如果要确保不存在竞争条件/并发dict访问,可以使用multiprocessing.Manager.dict()
。您的代码工作的事实让我相信,unique\u everseed
只在主进程中被调用,所以您是安全的。@Spencer-因为这是一个很大的列表(实际上是一个元组列表:我为这个问题简化了它),所以我不希望事先将其唯一化,正如我在问题中提到的:在运行中这样做似乎效率更高。@Jean-Françoisfare这不会导致这个过程的连续化吗?如果要锁定词典,则多处理的速度优势似乎可以忽略不计。@user2667066我当然不是多处理专家,但如果不先减少列表,我看不到优化此功能的方法。否则(除非我错了),不管您将不得不锁定一个共享资源来进行比较,这将导致您的代码实际上序列化。根据我的经验,最好在不共享资源的情况下完成像这样的多处理简单操作。