将集合转换为 python 中的列表的算法复杂度
Algorithmic complexity to convert a set to a list in python
在python中,当我将我的集合转换为列表时,这种任务的算法复杂度是多少?它只是对集合进行类型转换,还是需要将项目复制到不同的数据结构中?发生什么事了?
我很想知道复杂性是恒定的,就像 Python 中的许多东西一样。
您可以通过一个简单的基准测试轻松地看到这一点:
import matplotlib.pyplot as plt
x = list(range(10, 20000, 20))
y = []
for n in x:
s = set(range(n))
res = %timeit -r2 -n2 -q -o list(s)
y.append(res.best)
plt.plot(x, y)
这清楚地显示了线性关系 -- 模一些噪声。
(已编辑,因为第一个版本的基准测试有所不同)。
复杂度是线性的,因为所有引用都被复制到新容器中。但只有引用和是对象而不是对象 - 对于大对象来说可能很重要。
大多数情况下的时间复杂度为 O(n) 其中 n 是集合的大小,因为:
- 该集合作为 hashtable 实现,其基础数组大小受集合大小的固定倍数限制。迭代集合是通过迭代底层数组来完成的,所以它需要 O(n) 时间。
- 将一个项目添加到列表中需要 O(1) 的摊销时间,即使列表的基础数组最初没有分配到足够大以容纳整个集合;所以将 n 项附加到空列表需要 O(n) 时间。
但是,有一点需要注意,Python 的集合的基础数组大小基于集合对象的最大大小,不一定基于其当前大小;这是因为当从集合中删除元素时,底层数组不会重新分配为更小的大小。如果一个集合很小但过去更大,那么迭代它可能比 O(n).
慢
在python中,当我将我的集合转换为列表时,这种任务的算法复杂度是多少?它只是对集合进行类型转换,还是需要将项目复制到不同的数据结构中?发生什么事了?
我很想知道复杂性是恒定的,就像 Python 中的许多东西一样。
您可以通过一个简单的基准测试轻松地看到这一点:
import matplotlib.pyplot as plt
x = list(range(10, 20000, 20))
y = []
for n in x:
s = set(range(n))
res = %timeit -r2 -n2 -q -o list(s)
y.append(res.best)
plt.plot(x, y)
这清楚地显示了线性关系 -- 模一些噪声。
(已编辑,因为第一个版本的基准测试有所不同)。
复杂度是线性的,因为所有引用都被复制到新容器中。但只有引用和是对象而不是对象 - 对于大对象来说可能很重要。
大多数情况下的时间复杂度为 O(n) 其中 n 是集合的大小,因为:
- 该集合作为 hashtable 实现,其基础数组大小受集合大小的固定倍数限制。迭代集合是通过迭代底层数组来完成的,所以它需要 O(n) 时间。
- 将一个项目添加到列表中需要 O(1) 的摊销时间,即使列表的基础数组最初没有分配到足够大以容纳整个集合;所以将 n 项附加到空列表需要 O(n) 时间。
但是,有一点需要注意,Python 的集合的基础数组大小基于集合对象的最大大小,不一定基于其当前大小;这是因为当从集合中删除元素时,底层数组不会重新分配为更小的大小。如果一个集合很小但过去更大,那么迭代它可能比 O(n).
慢