Python 如何并行两个迭代器?

Python 如何并行两个迭代器?,python,parallel-processing,multiprocessing,Python,Parallel Processing,Multiprocessing,这是我问题的后续。我想做多处理.Pool.map(比较\u clusters,clusters\u 1,clusters\u 2),其中比较\u clusters是一个函数,clusters\u 1是一个对象列表,clusters\u 2也是一个对象列表。这个问题的答案清楚地表明,与map不同,多处理.Pool.map只能使用一个迭代器,在这种情况下,集群2必须是块大小 所以我的问题是,如何用两个迭代器并行化一个循环 代码 spectra_names, condensed_distance_ma

这是我问题的后续。我想做
多处理.Pool.map(比较\u clusters,clusters\u 1,clusters\u 2)
,其中比较\u clusters是一个函数,clusters\u 1是一个对象列表,clusters\u 2也是一个对象列表。这个问题的答案清楚地表明,与
map
不同,
多处理.Pool.map
只能使用一个迭代器,在这种情况下,
集群2
必须是块大小

所以我的问题是,如何用两个迭代器并行化一个循环

代码

spectra_names, condensed_distance_matrix, index_0 = [], [], 0 
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
    if index_0 == index_1:
        index_0 += 1
        spectra_names.append(clusters[index_1].get_names()[0])
    try:
        distance = 1/float(compare_clusters(clusters[index_1], clusters[index_2],maxiter=50))
    except:
        distance = 10
    condensed_distance_matrix.append(distance)
我是如何尝试将其并行化的

from multiprocessing import Pool
condensed_distance_matrix, spectra_names, index_0, clusters_1, clusters_2 = [], [], 0, [], []
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
    if index_0 == index_1:
        index_0 += 1
        spectra_names.append(clusters[index_1].get_names()[0])
    clusters_1.append(clusters[index_1])
    clusters_2.append(clusters[index_2])
pool = Pool()
condensed_distance_matrix_values = pool.map(compare_clusters, clusters_1, clusters_2)

for value in condensed_distance_matrix_values :
    try:
        distance = 1/float(value)
    except:
        distance = 10
    condensed_distance_matrix.append(distance)

如果我正确理解了您的代码,那么下面的代码应该可以工作

from multiprocessing import Pool
condensed_distance_matrix = []
spectra_names = []
index_0 = 0
cluster_pairs = []
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
    if index_0 == index_1:
        index_0 += 1
        spectra_names.append(clusters[index_1].get_names()[0])
    cluster_pairs.append((clusters[index_1], clusters[index_2]))
pool = Pool()
condensed_distance_matrix_values = pool.map(compare_clusters, cluster_pairs)

for value in condensed_distance_matrix_values :
    try:
        distance = 1/float(value)
    except:
        distance = 10
    condensed_distance_matrix.append(distance)
因此,与其创建两个包含单个集群的列表,不如创建一个包含集群对元组的列表。新列表中的每一对都是要比较的集群对。您可能需要相应地调整
compare\u clusters
功能


考虑到
Blckknght
的答案,您不需要迭代索引来创建一个配对列表,这就是
itertools.combinations
的用途。因此,您只需执行
pool.map(比较\u clusters,itertools.combines(clusters,2))
,因为combines已经返回元组列表。

在Python3.3及更高版本中,您可以使用
pool.starmap
。在早期版本中,您需要编写一个助手函数:

def do_comparison(tupl):
    x, y = tupl # unpack arguments
    return compare_clusters(x, y)

pool = Pool()
values = pool.map(do_comparison, itertools.combinations(clusters, 2))
condensed_distance_matrix = [1 / float(v) if v != 0 else 10 for v in values]
通过完全避免索引,而是直接生成2元组的集群值,我简化了很多事情。对于循环,您根本不需要您的top
。我还将反转代码简化为列表理解,而不是每个项调用一次
append
的循环

当然,您在循环中所做的另一件事是为
spectra\u名称
提取值。与其一次只做一个索引,我建议使用列表理解一次构建所有索引(它可以与上面的池内容分开):


谢谢在我的实际代码中,我有
spectra\u names.append(clusters[-1].get\u names())
在循环后获取最后一个值,但在copying@NiekdeKlein:啊,那确实更有意义。我将编辑以删除最后一段(以及它所谈论的片段)。
spectra_names = [c.get_names()[0] for c in clusters]