我已经解决了这个问题,我只想找到一种更有效的方法。我有一个很大的列表列表,我试图将大列表中的每个列表相互比较。
如何避免重复比较,比较已经比较过的列表?
Ex:big_list [0]已经与big_list [20]进行了比较,因此没有理由在循环中将big_list [20]与big_list [0]进行比较。
big_list= [[0.12, 0.939, -0.321, 6.342], [0.12, 0.939, -0.321,6.342], [0.0, 1.0, -0.0, -5.166], [0.0, 1.0, 0.0, -5.166], [0.0, 1.0, -0.0, -5.166], [-0.0, 1.0, 0.0, -5.166], [0.0, 1.0, 0.0, -5.166], [0.0, 1.0, 0.0, -5.166], [0.0,1.0, -0.0, -5.166], [0.0, 1.0, 0.0, -5.166], [-0.0, 1.0, -0.0, -5.166], [-0.0, 1.0, 0.0, -5.166], [-0.12, 0.939, 0.321, 0.282], [-0.12, 0.939, 0.321, 0.282], [0.12, 0.939, 0.321, -17.782], [0.12, 0.939, 0.321, -17.782], [-0.0, 1.0, 0.0, 0.834], [0.0, 1.0, 0.0, 0.834], [0.0, 1.0, 0.0, 0.834], [0.0, 1.0, 0.0, 0.834], [-0.12, 0.939, -0.321, 24.406], [-0.12, 0.939, -0.321, 24.406], [0.0, 0.874, -0.486, 21.883], [0.0, 0.874, -0.486, 21.883], [0.0, 0.874, 0.486, -14.598], [0.0, 0.874, 0.486, -14.598]]
for j in range(len(big_list)):
for k in range(len(big_list)):
if j!=k:
result=math.sqrt(sum([(a-b)**2 for a,b in zip(big_list[j],big_list[k])])))
之前,我通过设置一个特定的容差并将每个结果附加到一个新列表来解决这个问题,但我试图想出一个更有效的方法来做到这一点。最终,big_list可能会有100万个+列表
if result<=rel_tol and big_list[k] not in new_list:
new_list.append(big_list[k])
答案 0 :(得分:6)
而不是:
for j in range(len(big_list)):
for k in range(len(big_list)):
这样做(注意j+1
):
for j in range(len(big_list)):
for k in range(j+1, len(big_list)):
这样你的内部循环就跳过了你已经看过的所有索引,避免了重复的比较。
答案 1 :(得分:1)
@Justin回答的内容也是我的第一个想法,但经过反思后我不相信这对于真实big_lists
来说效率最高。相反,我会使用set()
的{{1}}:
tuples
仅使用内置迭代更短,更快。当然,如果你需要回到列表(由于某种原因需要可变的子列表),那么性能增益可能会丢失(不确定tbh,需要基准)但可读性不是:
tupled_set = set([tuple(i) for i in big_list])
new_list_of_tuples = list(tupled_set)
干杯
答案 2 :(得分:1)
不是将列表与两个for
循环相互比较,而是将它们转换为元组,并使用Counter
查看有多少个实例。然后,您可以遍历列表并选择每个具有多个实例的子列表的第一个匹配项。
from collections import Counter
c = Counter(tuple(l) for l in big_list)
new_list = []
for l in big_list:
t = tuple(l)
if c[t] > 1:
new_list.append(l)
c[t] = 0
这具有 O(n)时间复杂度,它将产生与原始代码相同的顺序。