我有以下程序:
import string
import itertools
import multiprocessing as mp
def test(word_list):
return list(map(lambda xy: (xy[0], len(list(xy[1]))),
itertools.groupby(sorted(word_list))))
def f(x):
return (x[0], len(list(x[1])))
def test_parallel(word_list):
w = mp.cpu_count()
pool = mp.Pool(w)
return (pool.map(f, itertools.groupby(sorted(word_list))))
def main():
test_list = ["test", "test", "test", "this", "this", "that"]
print(test(test_list))
print(test_parallel(test_list))
return
if __name__ == "__main__":
main()
输出是:
[('test', 3), ('that', 1), ('this', 2)]
[('test', 0), ('that', 0), ('this', 1)]
第一行是预期的正确结果。我的问题是,为什么 pool.map() 返回的结果与 map() 不同?
另外,我知道 6 项列表不是多处理的完美案例。这只是我在更大的应用程序中实现时遇到的问题的演示。
我正在使用 Python 3.5.1。
最佳答案
来自 https://docs.python.org/3.5/library/itertools.html#itertools.groupby :
The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list:
groups = [] uniquekeys = [] data = sorted(data, key=keyfunc) for k, g in groupby(data, keyfunc): groups.append(list(g)) # Store group iterator as a list uniquekeys.append(k)
我认为这里的问题是 Pool.map
试图切碎它的输入,并且在这样做时,它遍历 groupby
的结果,这有效地跳过了除了最后一组之外的所有元素。
您的代码的一个修复方法是使用类似 [(k, list(v)) for k, v in itertools.groupby(sorted(word_list))]
的东西,但我不不知道这对您的实际用例有多适用。
关于python - 为什么 pool.map() 和 map() 返回不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38807432/