python - 从 python 中的另一个排序列表中删除排序列表的快速和 pythonic/clean 方法是什么?

标签 python list python-2.7 sortedlist

我正在创建一种快速生成范围 (0, limit+1) 内素数列表的方法。在函数中,我最终从名为 primes 的列表中删除了名为 removable 的列表中的所有整数。我正在寻找一种快速且 pythonic 的方式来删除整数,因为我知道这两个列表总是排序的。

我可能是错的,但我相信 list.remove(n) 遍历列表,将每个元素与 n 进行比较。这意味着以下代码在 O(n^2) 时间内运行。

# removable and primes are both sorted lists of integers
for composite in removable:
    primes.remove(composite)

基于我的假设(这可能是错误的,请确认这是否正确)以及两个列表总是排序的事实,我认为下面的代码运行得更快,因为它只在列表上循环一次O(n) 时间。但是,它根本不是 pythonic 或干净的。

i = 0
j = 0
while i < len(primes) and j < len(removable):
    if primes[i] == removable[j]:
        primes = primes[:i] + primes[i+1:]
        j += 1
    else:
        i += 1

是否有内置函数或更简单的方法?最快的方法是什么?

旁注:我实际上并没有为上面的函数或代码计时。此外,可移动列表是否在此过程中被更改/销毁也没关系。

对于所有感兴趣的人,完整功能如下:

import math

# returns a list of primes in range(0, limit+1)
def fastPrimeList(limit):
    if limit < 2:
        return list()
    sqrtLimit = int(math.ceil(math.sqrt(limit)))
    primes = [2] + range(3, limit+1, 2)
    index = 1
    while primes[index] <= sqrtLimit:
        removable = list()
        index2 = index
        while primes[index] * primes[index2] <= limit:
            composite = primes[index] * primes[index2]
            removable.append(composite)
            index2 += 1
        for composite in removable:
            primes.remove(composite)
        index += 1
    return primes

最佳答案

这是非常快速和干净的,它确实 O(n) 设置成员检查,并且在摊销时间内它在 O(n) 中运行(第一行是 O(n) 摊销,第二行是 O(n * 1) 摊销,因为成员资格检查是 O(1) 摊销:

removable_set = set(removable)
primes = [p for p in primes if p not in removable_set]

这是对您的第二个解决方案的修改。它执行 O(n) 基本操作(最坏情况):

tmp = []
i = j = 0
while i < len(primes) and j < len(removable):
    if primes[i] < removable[j]:
        tmp.append(primes[i])
        i += 1
    elif primes[i] == removable[j]:
        i += 1
    else:
        j += 1
primes[:i] = tmp
del tmp

请注意常量也很重要。 Python 解释器执行 Python 代码的速度非常慢(即常量很大)。第二个解决方案有很多 Python 代码,对于 n 的小实际值,它确实比使用 set 的解决方案慢,因为 set 操作是在 C 中实现的,因此它们很快(即常数很小)。

如果您有多个可行的解决方案,请在典型的输入大小上运行它们,并测量时间。您可能会对它们的相对速度感到惊讶,这通常不是您所预料的。

关于python - 从 python 中的另一个排序列表中删除排序列表的快速和 pythonic/clean 方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26005454/

相关文章:

python - 根据日期标准合并 Pandas 中的列

python - Py2exe:编译没有GUI界面的Web服务器时是否需要 list 文件和w9xpopen.exe?

Python 使用不带标签的 beautifulsoup 打印抓取的数据

python - 为什么这个 sqlite python 3x 代码与 python 27 不兼容

python - Pandas 中基于规则的列重命名

python - python+django+Mysql 中的字符串值不正确

java - 如何查看arraylist java中的所有项目?

list - Lisp 两个列表相乘并相加两个值

python - 从包含 100,000 个整数的列表中检索两个最高的项目

python - 高效地获取列特定列表比较中的唯一条目