嵌套循环总是很慢吗?

时间:2020-09-01 17:29:43

标签: python nested-for-loop

似乎有很多与嵌套for循环的速度有关的问题和答案-我想我查看了其中的每一个!但是不幸的是,我仍然不确定为什么我的代码很慢。希望我能从您那里得到一些指导。

我每天下载一个有约116,000个条目的csv文件。在文件中不一致的位置添加和删除项目,因此每天我都想查看添加的内容和删除的内容。

对于旧列表和新列表,从csv到列表的条目获取都不需要花费任何时间,但是在代码的下一部分中,我遇到了很大的速度下降,尽管最后,它可以满足我的要求然后吐出差异-添加的项目和删除的项目。

列表中的116,000个项目中的每一个都是像这样的字典:

old or new = [{'Date Stamped': '', 'Name': '', 'Registration Number': '', 'Type': '', "Form Name':  '', 'URL': "}]

当我到达这一点时:

added = [i for i in new if not i in old]
removed = [i for i in old if not i in new]

需要25分钟才能完成!我觉得这已经很长时间了,但是我可能还不太清楚自己在做什么。

每个列表(旧列表和新列表)中都有〜116000个项目。那是因为我必须遍历约116,000个项目4次吗?

最后,它可以满足我的要求,但是它的运行速度似乎很慢;就是说,这确实是我第一次处理包含这么多项目的数据集,所以也许这当然是很合理的。

这很慢,因为它是嵌套的for循环吗?是因为尺寸慢吗?我绝对是一名业余爱好者,非常感谢大家的帮助。非常感谢。

1 个答案:

答案 0 :(得分:2)

实际上,,它很慢,因为它是嵌套的for循环,是因为的大小。

Python的element in list操作通过仅在整个列表中逐元素搜索所需的列表来进行。如果必须对new 中的每个单个元素执行此操作,则意味着您可能正在搜索old中每个元素的整个new

列表不是用于搜索的良好数据结构。如果有这样的用例,您应该做的是先将它们转换为set-一个无序的集合(但顺序可能无关紧要),该集合使用哈希表来确定元素是否为存在于其中。现在,与其按元素搜索整个数据结构,不如直接对要搜索的元素进行哈希处理,检查那里是否有元素,然后说是。

换句话说,element in set的效率比element in list高一个数量级。对于相对较小的开销成本(首先创建set而言),这减少了for循环所需的巨大时间: / p>

old_set = set(old)
new_set = set(new)
added = [i for i in new if not i in old_set]
removed = [i for i in old if not i in new]

此外,您甚至可以免除列表理解,因为set支持集合论中的运算-取两个集合之间的差(一个集合中的元素不在另一个集合中)就像将它们相减一样容易:

added = list(new_set - old_set)  # (new_set - old_set) is identical to new_set.difference(old_set)
removed = list(old_set - new_set)

这可能比列表理解甚至更有效,因为它已针对此用例进行了优化。

相关问题