初始化大小n列表的复杂性?

时间:2015-01-15 14:57:08

标签: python time-complexity

我需要创建一个包含n个项目的列表,这些项目都等于0,我使用了这个方法:

list = [0] * n

是时间复杂度O(n)还是O(1)?

如果它是O(n)是否是以O(1)复杂度实现此列表的一种方式?

3 个答案:

答案 0 :(得分:6)

创建 n 零的(密集)列表不能在O(1)中完成。您唯一的选择是查看一些稀疏或惰性数据结构。根据您要使用的内容,一个选项可能是itertools.repeat()

a = itertools.repeat(0, n)

将在O(1)中执行。当然,迭代它仍然是O( n )。

答案 1 :(得分:6)

O(1)时间内分配大对象的一种方法是(取决于您的基础操作系统)mmap.mmap,请参阅https://docs.python.org/2/library/mmap.html。但是,它不是具有所有灵活性的list - 它的行为就像一个可变的字符数组。

有时这仍然有用。在Python 3的最新版本中,您可以在memoryview的结果上放置mmap,并在eb调用.cast('L')上获取与整数序列相同的内存视图(两个操作) O(1))。 仍然不是列表 - 您不会获得list丰富的灵活性和全方位的方法 - 但是,更有可能提供帮助... < / p>

补充说:这确实提醒了许多年前我正在努力将一个大型CAD应用程序移植到当时全新的AIX版本和基于Power的IBM工作站时的时间。 malloc本质上是即时的 - 内核只是在幕后用CPU中的内存映射硬件做了一些魔术。

然而 ...实际上访问第一次远离malloc区域的项目(比如N字节形成其开头)可能需要{ {1}}因为所有需要的页面实际上都已分配 - 如果系统无法在您的进程的地址空间中找到或释放那么多页面,那么甚至可能导致崩溃(IOW,{{1 &#34;首先过度使用&#34;内存!)。

正如您可以想象的那样,对最初为O(N)的更传统实现开发的应用程序造成破坏性破坏:应用程序检查malloc的返回值 - 如果为0,则需要采取适当的补救措施动作(最坏的情况,只是让用户知道他们想要的操作由于缺乏记忆而无法执行);否则,它假设它刚刚分配的内存实际上是 ......有时最终崩溃了&#34;随机&#34;沿途的景点: - )。

解决方案只是中等难度 - 将malloc包装到一个函数中,后缀实际上触及&#34;名义上分配的&#34;的正确子集。页面,以确保它们实际上都在那里( 很难捕捉到在这种时候可能出现的低级错误,但最终我设法找到了一种方法,只需要一点汇编语言编码我记得)。当然,这个确实再次包裹malloc malloc ......似乎没有免费午餐这样的东西,他们有认为 - ?!)

我不确定malloc在您感兴趣的所有平台上从这一点开始实际表现如何 - 没有什么可以实现的,但实际上是实验,我猜! - )(如果它那么结果提供免费午餐,至少在流行的平台上,现在 值得庆祝: - )。

答案 2 :(得分:0)

你也可以为发生器推出自己的方法:

def foo(num, times):
    for a in range(0, times):
        yield num

在我的机器中进行分析后:

import timeit

code = """
def foo(num, times):
    for a in range(0, times):
        yield num
"""
print timeit.timeit("foo(0,1)", setup=code)
print timeit.timeit("foo(0,2**8)", setup=code)

# 0.310677051544
# 0.32208776474