我知道列表与数组不同。但是,O(1)?这意味着访问列表中的元素与访问dict中的元素一样快,我们都知道这不是真的。 我的问题基于this document:
list ---------------------------- | Operation | Average Case | |-----------|--------------| | ... | ... | |-----------|--------------| | Get Item | O(1) | ----------------------------
列表中的查找是O(n),字典中的查找是分摊的O(1), 关于数据结构中的项目数。
如果第一个文档是真的,那么为什么访问一个dict比访问一个列表更快,如果它们具有相同的复杂性?
有人可以对此作出明确的解释吗?我会说它总是取决于列表/字典的大小,但我需要更多地了解它。
答案 0 :(得分:8)
获取项目正在获取特定索引中的项目,而查找意味着搜索列表中是否存在某个元素。为此,除非对列表进行排序,否则您将需要迭代所有元素,并进行O(n)
Get Item操作,这将导致O(n)查找。
字典是在底层维护一个智能数据结构(哈希表),因此您不需要查询O(n)
次来查找该元素是否存在,而是需要固定次数(平均大小写),导致O(1)
查找。
答案 1 :(得分:1)
访问索引l
n
处的列表l[n]
是O(1),因为它没有实现为Vanilla链接列表,因此需要在指针之间跳转(值,next- ->)n次达到单元格索引n。
如果内存是连续的并且条目大小将是固定的,那么达到特定条目将是微不足道的,因为我们知道将条目大小跳转n倍(例如C中的经典数组)。
但是,由于list的条目大小是可变的,因此python实现仅将连续的内存列表用于指向值的指针。这使对列表(l [n])进行索引的操作的开销与列表的大小或索引的值无关。
有关更多信息,请参见http://effbot.org/pyfaq/how-are-lists-implemented.htm
答案 2 :(得分:1)
这是因为Python将列表中每个节点的地址存储到一个单独的数组中。当我们想要第n个节点上的元素时,我们要做的就是查找地址数组的第n个元素,该元素为我们提供列表中第n个节点的地址,通过该地址我们可以在{{1}中获得该节点的值}复杂度。
Python做了一些巧妙的技巧,使这些数组随着列表的增长而扩展。因此,我们获得了列表的灵活性和数组的速度。这里要权衡的是,每当列表增长到一定程度时,编译器就必须为地址数组重新分配内存。
amit在他对这个问题的回答中解释了为什么字典中的查找比列表中的查找更快。
答案 3 :(得分:-1)
从严格的计算机科学角度来看,我能看到的最小值是O(log n)