我有一个“箱子定义”的排序列表,我想整合一下。该列表看起来像:
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万+“盒子”)时,过程非常非常慢。
有没有一种聪明的方法来并行化这个列表“抽取”过程或者可能加快这个过程?
答案 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