Python内置方法中嵌套模块的大O表示法

Python内置方法中嵌套模块的大O表示法,python,performance,methods,coding-style,big-o,Python,Performance,Methods,Coding Style,Big O,我想知道确定Python中内置方法背后的大O值的基本原理。鉴于以下操作: i_arr = ['1','2','5','3','4','5','5'] s_arr = sorted(set(i_arr)) 我的基本原理是,这是排序(set)=n^2表示两个嵌套循环 根据建议,我深入研究了更高级别的模块,作为Python源代码中原始函数的一部分: def sorted(lst): l = list(lst) l.sort() return l

我想知道确定Python中内置方法背后的大O值的基本原理。鉴于以下操作:

i_arr = ['1','2','5','3','4','5','5']

s_arr = sorted(set(i_arr))
我的基本原理是,这是
排序(set)=n^2
表示两个嵌套循环

根据建议,我深入研究了更高级别的模块,作为Python源代码中原始函数的一部分:

 def sorted(lst):
        l = list(lst)
        l.sort()
        return l

def sort(self):
        sortable_files = sorted(map(os.path.split, self.files))

def set(self):
        if not self._value:
            self._value = True

            for fut in self._waiters:
                if not fut.done():
                    fut.set_result(True)

现在我真的很困惑:)

排序算法的复杂度上限通常是O(n*log(n)),如图所示。 然后,它取决于将数组强制转换到集合所需的时间。从您发布的示例中,我们可以看到列表被迭代,并且在每个步骤中,检查值是否已经在集合中。 根据对集合中元素存在性的检验,集合的复杂性为常数O(1),因此集合的整体构造由于迭代所有元素而具有复杂性O(n)。 但假设它是通过逐个添加每个元素来实现的,我们必须迭代列表以将其转换为集合,即O(n),然后我们对其进行排序,即O(n*log(n)),结果是总复杂度O(n*log(n)+n)=O(n*log(n))

更新:

映射也具有线性复杂性,因为它迭代整个集合并映射每个元素,但由于线性函数的增长速度比n*log(n)慢,因此这里的任何线性操作都不会影响O(n*log(n)),因此,即使使用映射,渐近复杂性也保持不变。

(n logN)是某些排序算法的下限​ 像快速排序、堆排序、合并排序。它们是基于比较的通用算法。在最坏的情况下,它可以是O(N*N)

如果元素是数字的,那么有O(N)个上界算法,比如基数排序、计数排序和桶排序

如果我们在谈论python库的“排序”实现,那么它就是排序实现。TimSort是一种优化的合并排序算法。它比常规的mergesort算法稳定且速度更快。在最坏的情况下,它在O(N log N)上运行,在最好的情况下(当列表已经排序时)在O(N)上运行。

超出“通用排序”性能答案;正如您所提到的
sorted()
我假设您在询问python中内置方法背后的大O值

那么python正在使用,;引用维基百科:

Timsort是一种混合稳定排序算法,源于合并排序和插入排序,设计用于处理多种实际数据

在最坏的情况下,Timsort需要进行O(n logn)比较来对n个元素的数组进行排序。在最佳情况下,当输入已经排序时,它以线性时间运行,这意味着它是一种自适应排序算法


函数
sorted
可能会对传递的项目进行排序。有许多可能实现的
排序
,每个都具有不同的性能特征。您的示例没有告诉我们正在使用的
sorted
的具体实现。@AndrewShepherd
sorted
是一个python内置函数。所以问题归结为:python默认值在做什么……组合是加法的,而不是乘法的。在O(n)时间内创建集合,然后在O(n)时间内对结果集合进行排序。忽略符号的滥用,O(n)+O(n lgn)=O(n+n lgn)=O(n lgn)。是的,我在写完后立即纠正了这个错误。