Consider there are some lists of integers as:
#--------------------------------------
0 [0,1,3]
1 [1,0,3,4,5,10,...]
2 [2,8]
3 [3,1,0,...]
...
n []
#--------------------------------------
这个问题是要合并至少有一个共同元素的列表。因此,仅针对给定部分的结果如下:
#--------------------------------------
0 [0,1,3,4,5,10,...]
2 [2,8]
#--------------------------------------
在大数据集上,如何最有效地实现此操作(元素仅为数字)?
树形结构是否值得考虑?
目前我通过将列表转换为set
并迭代交集来完成工作,但速度较慢!此外,我觉得这是非常基础的!另外,我的实现缺少某些东西(未知),因为有时一些列表仍然未合并!话虽如此,如果您建议自己实现,请慷慨提供一个简单的示例代码[显然,Python 是我最喜欢的:)]或伪代码。
更新 1:
以下是我使用的代码:
#--------------------------------------
lsts = [[0,1,3],
[1,0,3,4,5,10,11],
[2,8],
[3,1,0,16]];
#--------------------------------------
该函数有(漏洞!!):
#--------------------------------------
def merge(lsts):
sts = [set(l) for l in lsts]
i = 0
while i < len(sts):
j = i+1
while j < len(sts):
if len(sts[i].intersection(sts[j])) > 0:
sts[i] = sts[i].union(sts[j])
sts.pop(j)
else: j += 1 #---corrected
i += 1
lst = [list(s) for s in sts]
return lst
#--------------------------------------
结果是:#--------------------------------------
>>> merge(lsts)
>>> [0, 1, 3, 4, 5, 10, 11, 16], [8, 2]]
#--------------------------------------
更新2:
根据Niklas Baumstark提供的代码,对于简单情况来说,速度要稍快一些。还没有测试“Hooked”提供的方法,因为它是完全不同的方法(顺便说一句,它看起来很有趣)。
对于所有这些方法的测试程序可能非常困难或不可能确保结果。我将使用的真实数据集非常庞大且复杂,因此仅通过重复无法追踪任何错误。也就是说,在将其作为模块放入大型代码之前,我需要100%满意该方法的可靠性。因此,现在对于简单的数据集而言,Niklas的方法更快且答案当然是正确的。
但是我如何确信它对于真正的大型数据集有效呢? 因为我将无法通过视觉追踪错误!
更新3: 请注意,对于此问题,方法的可靠性比速度更重要。最终我希望能够将Python代码转换为Fortran以获得最大的性能。
更新4:
这篇文章和慷慨给出的答案、建设性的评论都有很多有趣的观点。我建议仔细阅读所有内容。感谢提出问题、给出惊人的答案、建设性的评论和讨论。