【问题标题】:Python - large list efficiency [duplicate]Python - 大列表效率[重复]
【发布时间】:2014-10-06 21:40:16
【问题描述】:

我有一个函数unique(a),它接受一个数字列表a,并且只返回每个值中的一个。同时,它维护列表的顺序。我还有一个函数big_list(n),它生成len(n) 的列表。

我反转列表方向的原因是,在删除值时,它会将它们从原始列表的后面删除,只是为了使修改后的列表在与原始列表进行比较时更加干净和可读。

当我创建的列表长度相对较小时,该函数可以工作,但是当我获得更大的长度时,例如 1,000,000 为 ex,执行时间需要 FOREVER。

如果有人可以帮助我加快我的功能,那就太好了!

仅供参考:我需要在函数的某处使用一个集合来完成我正在处理的任务。我仍然需要从后面删除列表项。

提前致谢!

def big_list(n) :
    # Create a list of n 'random' values in the range [-n/2,n/2]
    return [ randrange(-n//2, n//2) for i in range(n) ]

def unique(a) :
    a = a[::-1]
    b = set(a)
    for i in b :
        while a.count(i) != 1 :
            a.remove(i)
            a.count(i)
    a = a[::-1]
    return a

【问题讨论】:

  • Set 已经是唯一的了。它不会包含重复项。即 x=set(big_list(10k)), x 将没有重复项。
  • 这难道不是时间复杂度最差的例子吗?

标签: python performance loops


【解决方案1】:

您的算法在移动元素时做了很多额外的工作。考虑:

def unique(a):
    b = set()
    r = []
    for x in a:
        if x not in b:
            r.append(x)
            b.insert(x)
    return r

【讨论】:

  • 谢谢!像您在示例中所做的那样,在迭代列表时创建一个新列表通常更好吗?
  • Python 在以这种方式创建新列表方面非常有效。另一种方法是执行大量 .remove() 操作,这些操作必须大量移动元素,特别是如果您有很多元素要一个一个删除。
【解决方案2】:

每次调用a.count(i) 时,它都会遍历整个列表以计算出现次数。这是一个 O(n) 操作,您一遍又一遍地重复。当您考虑到外部 for i in b: 循环的 O(n) 运行时间时,整体算法复杂度为 O(n2)。

while 循环内有第二个不必要的 a.count(i) 也无济于事。那个电话除了浪费时间什么都没做。

这整个问题可以在 O(n) 时间内完成。您最好的选择是完全避免list.count(),并弄清楚如何循环列表并自己计算元素。如果你很聪明,你可以一次完成所有事情,不需要嵌套循环(或隐式嵌套循环)。

【讨论】:

  • 感谢您的建议!
【解决方案3】:

您可以在this address 找到“独特”功能的全面基准。我个人最喜欢的是

def unique(seq):
    # Order preserving
    seen = set()
    return [x for x in seq if x not in seen and not seen.add(x)]

因为它是最快的并且可以保持顺序,同时巧妙地使用集合。我认为是 f7,它在 cmets 中给出。

【讨论】:

  • 我以前看过那个页面,只是我没有意识到有一个 f7。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 2012-07-09
  • 2012-08-18
  • 2013-08-28
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多