python 多处理 pool.starmap 不起作用

python multiprocessing pool.starmap does not work

我正在使用多处理 pool.starmap 函数。我发现了一个奇怪的问题。

from multiprocessing import Pool
p = multiprocessing.Pool()

NODE = [1,2,3,4];
PageRank = [0.25,0.25,0.25,0.25];
Destination = [[2,3,4],[3,4],[1,4],[2]];

Data = zip(NODE,PageRank,Destination)

所以我使用zip函数创建了一个数据集Data,这是一个列表,每个条目都是一个长度为3的元组。然后我调用函数

p.starmap(MyFunction, zip(NODE,PageRank,Destination))

效果很好。

然而,当我输入

p.starmap(MyFunction, Data))

它输出空列表[]!!!!我真的不知道发生了什么。我只是把 zip(NODE,PageRank,Destination) 换成了 Data,应该是一样的吧?

是不是因为我使用的是 Jupyter notebook 导致的?

此答案仅在

时有效
  • 您正在使用 Python 3,并且
  • 您正在使用未出现在 post
  • 中的 zip 对象进行操作(例如调试打印)

在Python2中,zip(...)returns一个list;但是在 Python 3 中,它 returns 是一个 zip 对象(这与您在 post 中所说的列表不同)。

zip 对象是一个迭代器,因此只能迭代一次。到达迭代器的末尾后,任何再次迭代它的尝试都不会产生任何结果。例如,

>>> z = zip([1, 2], [3, 4])
>>> for x in z:
...     x
... 
(1, 3)
(2, 4)
>>> for x in z:
...     x
... 
>>> list(z)
[]

关于我的第二个要点,我怀疑你正在做一些看似无害的事情,比如在将 Data 的所有元素作为参数传递给pool.starmap。如果是这种情况,您将耗尽迭代器,然后有效地告诉 pool.starmapMyFunction 应用于绝对没有的东西。

要解决此问题,您有三种选择。

  1. 按照您提到的第一种方式执行此操作,即在对 pool.starmap.
  2. 的调用中创建 zip 对象
  3. 在将 Data 传递给 pool.starmap 之前不要循环 Data
  4. 将 zip 对象转换为列表 (Data = list(zip(NODE,PageRank,Destination)))。然后它是一个 iterable 并且您可以根据需要对其进行多次迭代。

依我愚见,这个问题只是Python新人的一个成年礼。如果它适用于你并且你想了解更多,你应该阅读 iteratoriterable 之间的区别,也许从 this SO post.