并行化Python中的列表合并

时间:2013-05-13 21:02:19

标签: python list parallel-processing

我有一个“箱子定义”的排序列表,我想整合一下。该列表看起来像:

big_list = [\
# ...
# ...
[3, 4, 5, 4, 5, 6, 65],\
[3, 4, 5, 4, 5, 6, 60],\
[3, 4, 5, 4, 5, 6, 55],\
[3, 4, 5, 4, 5, 6, 52],\
[3, 4, 5, 4, 5, 6, 23],\
[3, 4, 5, 4, 5, 6, 17],\
[3, 4, 5, 4, 5, 6, 0],\
[5, 8, 9, 6, 9, 10, 90],\
[5, 8, 9, 6, 9, 10, 84],\
[5, 8, 9, 6, 9, 10, 32],\
[5, 8, 9, 6, 9, 10, 0],\
# ...
# ...
[750, 800, 900, 751, 801, 901, 97],\
[750, 800, 900, 751, 801, 901, 24],\
[750, 800, 900, 751, 801, 901, 17],\
[750, 800, 900, 751, 801, 901, 16],\
[750, 800, 900, 751, 801, 901, 0]\
# ...
# ...
]

框“格式”为:[x1,y1,z1,x2,y2,z2,属性],我们可以假设dx = 1,dy = 1,dz = 1

此外,我们可以假设列表已按以下方式排序:

big_list=sorted(big_list, key=lambda n:n[6], reverse=True)
big_list=sorted(big_list, key=lambda n:n[2])
big_list=sorted(big_list, key=lambda n:n[1])
big_list=sorted(big_list, key=lambda n:n[0])

列表可能是几百万个项目,我希望减少列表,以便任何离散的“框”只获得最高的“属性”...所以在这种情况下的东西如:

reduced_big_list = [\
[3, 4, 5, 4, 5, 6, 65],\
[5, 8, 9, 6, 9, 10, 90],\
[750, 800, 900, 751, 801, 901, 97]\
]

我目前在此列表中使用的方法类似于:

i = 0

while i < len(big_list)-1:
     if big_list[i][0]==big_list[i+1][0]\
     and big_list[i][1]==big_list[i+1][1]\
     and big_list[i][2]==big_list[i+1][2] \
     and big_list[i][6] >= big_list[i+1][6]:
          del big_list[i+1]
     else:
          i=i+1

问题是,当列表“长”(1000万+“盒子”)时,过程非常非常慢。

有没有一种聪明的方法来并行化这个列表“抽取”过程或者可能加快这个过程?

3 个答案:

答案 0 :(得分:1)

缓慢是对del的调用,它会将列表的完整尾部的项目移动一步。在您的情况下,只是不要使用del。换一个新列表,从空列表开始,append你要保留的项目。

答案 1 :(得分:1)

原因很慢的是每次你del一行需要一段线性时间,使整个过程为O(n ^ 2)。

如果不是从原始列表中删除行,而是将要保留的行追加到新列表中,它应该更快。

但是还有其他可能更多的Pythonic方法可以执行相同的操作。例如,使用itertools.groupby(假设列表按照您的指定排序):

from itertools import groupby
new_list = [next(group) for val,group in groupby(big_list, key=lambda x: x[:3])]

这将按前3个元素对列表项进行分组,并返回每个组中第一个项目的列表。

答案 2 :(得分:1)

布尔and首先计算左表达式。如果第一个表达式为真,它仅评估右手表达式。由于您已经对列表进行了排序,因此相邻元素可能比后面的元素具有相同的第0个元素。试试

i = 0

while i < len(big_list)-1:
    if big_list[i][2]==big_list[i+1][2]\
    and big_list[i][1]==big_list[i+1][1]\
    and big_list[i][0]==big_list[i+1][0]\
    and big_list[i][6] >= big_list[i+1][6]:
        del big_list[i+1]
    else:
        i=i+1