python Wiki上说:"使用集和字典进行成员资格测试比搜索序列O(n)更快,O(1)。测试" a in b"时,b应该是集合或字典,而不是列表或 元组。"
每当速度在我的代码中很重要时,我就一直使用集代替列表,但是最近我一直在想为什么集比列表快得多。 任何人都可以解释一下,或者让我指向可以解释这一点的消息源,这是为了在python中更快地进行设置吗?
微调-哈希表
list:假设您正在壁橱中寻找袜子,但是您不知道袜子在哪个抽屉中,因此您必须逐个抽屉地搜索,直到找到它们为止(或者可能永远不会找到)。这就是我们所说的O(n),因为在最坏的情况下,您将查看所有抽屉(其中n是抽屉数)。
set:现在,想象您还在壁橱里寻找袜子,但是现在您知道了袜子在哪个抽屉里,比如说在第三个抽屉里。因此,您将只在第三个抽屉中搜索,而不是在所有抽屉中搜索。这就是我们所说的O(1),因为在最坏的情况下,您只会看到一个抽屉。
使用实时示例是理解或教导任何事物的最佳方法。 做得好!
@juliomalegria袜子抽屉代表list / set中的元素还是元素的存储位置?
那么,为什么我们"知道袜子在第三个抽屉中"的原因使得要查询的值被散列并且可以直接转到相应的内存位置以查找数据?
这是解决该问题的完美ELI5!
多么生动,简洁的示例说明了big-O和哈希集的价值! 荣誉
答案的一半不正确。 在最坏的情况下,集合查找不是O(1)。
集是使用哈希表实现的。每当将对象添加到集合中时,set对象在内存中的位置都是使用要添加的对象的哈希值确定的。在测试成员资格时,基本上需要做的只是查看对象是否在其哈希确定的位置,因此此操作的速度不取决于集合的大小。相反,对于列表,需要搜索整个列表,随着列表的增长,列表的搜索速度会变慢。
这也是设置不保留您添加的对象顺序的原因。
请注意,集合通常不会比列表快—成员资格测试对于集合来说更快,因此删除元素也是如此。只要您不需要这些操作,列表通常就会更快。
我认为您需要仔细阅读一本有关数据结构的书。基本上,Python列表实现为动态数组,而集实现为哈希表。
这些数据结构的实现赋予它们根本不同的特征。例如,哈希表的查找时间非常快,但无法保留插入顺序。
很抱歉,无法恢复旧线程。 但是对书有什么建议吗?
list:假设您正在寻找笔,但是您不知道您的笔在哪个抽屉中,因此您必须逐个抽屉地搜索抽屉,直到找到它为止(或者可能永远不会找到)。 这就是我们所说的O(n),因为在最坏的情况下,您将查看所有抽屉(其中n是抽屉数)。
set:现在,假设您还在寻找笔,但是现在您知道笔在哪个抽屉中,例如在第8个抽屉中。 因此,您将只在第8个抽屉中搜索,而不是在所有抽屉中搜索。 这就是我们所说的O(1),因为在最坏的情况下,您只会看到一个抽屉。
基本上,Python列表被实现为dynamic arrays,集合被实现为hash tables。
虽然到目前为止,我还没有测量过与python相关的任何性能,但我仍然想指出,列表通常更快。
是的,您有O(1)对O(n)。但是请始终记住,这仅提供有关某些事物的渐近行为的信息。这意味着,如果您的n很高,则O(1)总是会更快-从理论上讲。但是实际上,n通常需要比通常的数据集大得多。
因此,集合本身并不比列表本身快,而仅在必须处理许多元素时才如此。
Python使用具有O(1)查找的哈希表。
基本上,取决于您正在执行的操作...
*要添加元素-集合不需要移动任何数据,它要做的就是计算一个哈希值并将其添加到表格中。对于列表插入,则可能有要移动的数据。
*要删除元素-集合所需要做的就是从哈希表中删除哈希条目,对于列表而言,它可能需要移动数据(平均为数据的1/2)。
*对于搜索(即in运算符)-一组只需要计算数据项的哈希值,请在哈希表中找到该哈希值(如果存在)-然后是bingo。对于列表,搜索必须依次查找每个项目-平均列表中所有术语的1/2。即使对于成千上万的项目,一组搜索也将更快。
列表必须一个一个地搜索,其中一个集合或字典都有一个索引,可以更快地进行搜索。