我想知道是否还有运行多个线程并将不同线程的结果分配给dict中的特定键。像这样:
from joblib import Parallel, delayed
from math import sqrt
dict_of_sqrt = {}
i = {'a':1,'b':2,'c':3,'e':4}
dict_of_sqrt[k] = Parallel(n_jobs=2)(delayed(sqrt)(v**2) for k, v in i.items())
结果应该是具有相同键的字典并分配并行计算的新值:
dict_of_sqrt = {'a':1, 'b':1.41, 'c'=1.73, 'e'=2}
它假设是安全的,因为我写的是不同的键(没有重叠)。但是,我还没有找到一个例子。
答案 0 :(得分:0)
如果你正在进行IO操作,那么你可以使用Threads,但是如果你完成CPU密集操作,你必须考虑GIL,所以我会处理。
如果您使用的是多处理库,我认为Pool是最适合您的对象,因为您希望控制执行线程的数量。为了执行该过程,您可以使用map或apply_async和回调函数。 您可以在此处阅读有关map vs apply_async的更多信息:Python multiprocessing.Pool: when to use apply, apply_async or map?
我喜欢使用Queue对象将数据返回到父进程,因为它是多处理/线程安全的,但它确实有超越队列和处理结果的空头。
以下是基本用法的快速示例。
import multiprocessing
from Queue import Empty
from math import sqrt
import string
def my_sqrt(*args):
k, v, q = args[0]
q.put({k: sqrt(v)})
def main():
p = multiprocessing.Pool(2)
m = multiprocessing.Manager()
q = m.Queue()
# This is just to generate data.
l = [(k, (v + 1)**2, q) for v, k in enumerate(string.lowercase)]
p.map(my_sqrt, l)
# Go over the Q
d = dict()
try:
while 1:
m = q.get_nowait()
d.update(m)
except Empty:
pass
print d
if __name__ == '__main__':
main()
答案 1 :(得分:0)
更新
from multiprocessing import Pool
from time import sleep
from random import choice
import math
# function that may take up to 5 seconds
def myroot(t):
sleep(choice(range(5)))
return {t[0]:math.sqrt(t[1])}
if __name__ == '__main__':
# dictionary keys -> n
# value should be n**2
d = {'a':1,'b':2,'c':3,'e':4}
dt = [(i,d[i]) for i in d]
# spawn 3 processes
pool = Pool(3)
# iterate all keys, feed them in sqr fuc
results = pool.map(myroot, dt)
# update object d, with result from each process
[d.update(i) for i in results]
print(d)
答案 2 :(得分:0)
您可以将值并行计算并作为元组对返回新键和值。在调用过程中,您只需要将其转换为字典。
from math import sqrt
from multiprocessing import Pool
i = {'a':1,'b':2,'c':3,'e':4}
# pass me to `starmap`
def sqrtval(k, v):
return k, sqrt(v)
# pass me to `map`
def sqrtval_py2(kv):
k, v = kv
return k, sqrt(v)
tup = Pool().starmap(sqrtval, i.items())
# tup = Pool().map(sqrtval_py2, i.items())
print(tup)
print(dict(tup))
Python 2没有starmap
的{{1}}方法,所以要解决这个问题,multiprocessing.Pool
必须接受一个键/值元组并在映射函数中使用它。还提供了python 2替代方案。