我需要创建一个包含n个项目的列表,这些项目都等于0,我使用了这个方法:
list = [0] * n
是时间复杂度O(n)还是O(1)?
如果它是O(n)是否是以O(1)复杂度实现此列表的一种方式?
答案 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