列表和字典:哪个更快

时间:2019-11-20 00:46:34

标签: python-3.x

我有以下代码通过交换元素对来对列表进行排序:

-----BEGIN CERTIFICATE----- 
MIIDijCCAvOgAwIBAgIJAKRvtQxONVZoMA0GCSqGSIb3DQEBBAUAMIGLMQswCQYD   
aXJlbGVzcyBOZXR3b3JrczEMMAoGA1UECxMDVEFDMSMwIQYDVQQDExpteXNlcnZl 
ci5hcnViYW5ldHdvcmtzLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA 
zRwqc9prVXycGhHcsAjGPzC2MKU4DhXSr86Z89Jk8/cXEJBJ0C/NgdAqqDgxneUh 
nVyxGxODa7BNGAWSagdCsKLrbkchr479E3xLfgdc3UzAJITLGCXGiQ66NwQDyM5I 
YWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxIDAeBgNVBAoTF0FydWJhIFdp 
cmVsZXNzIE5ldHdvcmtzMQwwCgYDVQQLEwNUQUMxIzAhBgNVBAMTGm15c2VydmVy 
LmFydWJhbmV0d29ya3MuY29tggkApG+1DE41VmgwDAYDVR0TBAUwAwEB/zANBgkq 
hkiG9w0BAQQFAAOBgQBp71WeF6dKvqUSO1JFsVhBeUesbEgx9+tx6eP328uL0oSC 
fQ6EaiXZVbrQt+PMqG0F80+4wxVXug9EW5Ob9M/opaCGI+cgtpLCwSf6CjsmAcUc 
b6EjG/l4HW2BztYJfx15pk51M49TYS7okDKWYRT10y65xcyQdfUKvfDC1k5P9Q== 
-----END CERTIFICATE-----

第二个功能比第一个功能快得多。但是,有人告诉我字典比列表快。 这是什么原因?

1 个答案:

答案 0 :(得分:3)

列表是数据结构,而字典是数据结构。说一个“比另一个”“更快”是没有意义的,比说苹果比橙色要快还没有多大意义。一个可能增长更快,您可能可以更快地食用另一个,并且当它们掉落时它们可能都以相同的速度掉落在地上。并不是更快的结果,而是您使用它的结果。

如果您的问题是您有一个字符串序列,并且想知道给定字符串在序列中的位置,请考虑以下选项:

  • 您可以将序列存储为列表。使用.index方法查找给定字符串的位置需要linear search,并在O(n)时间内遍历列表。
  • 您可以存储字典映射字符串到其位置。要找到给定字符串的位置,需要在O(1)时间中在字典中查找它。

因此,使用字典解决问题的速度更快 。 但也请注意,在第一个函数中,您正在使用列表的.index方法构建字典-这意味着在O(n)时间中分别进行n个线性搜索,在O(n ^ 2)时间中构建字典< strong>,因为您使用列表的原因是列表速度较慢。如果您在不进行线性搜索的情况下构建字典,则将花费O(n)的时间:

    val_2_indx = { val: i for i, val in enumerate(arr) }

但是现在考虑一个不同的问题。您有一个数字序列,并且它们恰好是从1到n的数字(按某种顺序)。您希望能够在序列中查找数字的位置:

  • 您可以将序列存储为列表。要找到给定数字的位置,需要再次在O(n)时间内进行线性搜索。
  • 您可以像以前一样将它们存储在字典中,并在O(1)时间进行查找。
  • 您可以将逆序列存储在列表中,以便lst[i]保持原始序列中值i位置。之所以可行,是因为每个排列都是可逆的。现在,获得i的位置是一个简单的列表访问,时间为O(1)。

这是一个不同的问题,因此可能需要花费不同的时间才能解决。在这种情况下,列表和字典都允许在O(1)时间内求解,但是事实证明使用列表更有效。通过字典中的键获取比通过列表中的索引获取具有更长的恒定时间,因为通过字典中的键获取需要计算哈希,然后探测数组以找到正确的索引。 (从列表中获取只需要访问一个已知索引处的数组。)

第二个问题是第二个功能中的问题。参见此部分:

    temp = [0] * (len(arr) + 1)
    for pos, val in enumerate(arr):
        temp[val] = pos

这将创建一个列表temp,其中temp[val] = posarr[pos] == val处。这意味着列表temparr的反排列。在代码的后面,temp仅用于通过索引获取这些位置,这是O(1)运算,并且比在字典中查找键要快。