Python 我应该把莱恩(名单)存放在什么地方吗?

Python 我应该把莱恩(名单)存放在什么地方吗?,python,Python,代码1: 代码2: list=[1,2,3,4,5] for i in range(len(list)): for j in range(len(list)): print(i+j) 代码2是否比代码1快?是代码2比代码1快 `每次计算len时,代码1中都有原因,这意味着您正在计算长度0(len(list)*len(list)),而在代码2中,您只计算列表的一个时间长度的区域是o(len(list)` list=[1,2,3,4,5] l=len(list) for i

代码1:

代码2:

list=[1,2,3,4,5]
for i in range(len(list)):
    for j in range(len(list)):
        print(i+j)
代码2是否比代码1快?

是代码2比代码1快

`每次计算len时,代码1中都有原因,这意味着您正在计算长度0(len(list)*len(list)),而在代码2中,您只计算列表的一个时间长度的区域是o(len(list)`

list=[1,2,3,4,5]
l=len(list)
for i in range(l):
    for j in range(l):
        print(i+j)
输出:

def abc():
    list=[1,2,3,4,5]
    for i in range(len(list)):
        for j in range(len(list)):
            print(i+j)

def mmm():
    list = [1, 2, 3, 4, 5]
    l = len(list)
    for i in range(l):
        for j in range(l):
            print(i + j)

from time import time
t0 = time()
abc()
t1 = time()
mmm()
t2 = time()

print 'function1  takes %f' %(t1-t0)
print 'function2 takes %f' %(t2-t1)

没有明显的区别。
len(somelist)
是一种非常快速的操作。列表的长度存储在内部,因此当您询问列表的长度时,几乎不需要做什么工作。

回答标题中的问题:

我应该把
len(list)
存储在什么地方吗

获取列表的长度需要O(1)个时间,通常相当快。在第一个代码片段中,您将获得列表的长度O(n)个时间,但与算法的O(n2)个时间复杂度相比,这并不重要

严格地说,我们当然不知道计算列表长度的时间复杂性(因为任何Python解释器都可能以不同的方式进行计算)

它包含一个字段
allocated
,该字段存储可在固定时间内检索的已占用单元格数

然而,您的程序在某种意义上是奇怪的,因为您迭代列表的索引,而不是列表的元素。如果您想处理元素,则使用以下方法更为优雅和高效:

typedef struct {
    PyObject_VAR_HEAD
    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

最后,我想补充一点,Python并不是真正设计成最高效的编程环境。Python选择了程序员的方便而不是速度(因为其基本原理是开发时间比处理时间更昂贵)。因此,如果多次获取列表的长度确实是一个关键问题,那么Python可能不是开始处理列表的好选择。在这种情况下,您最好使用像
numpy
这样的库,这些库设计用于批处理。这些库将一些数组处理函数与Python接口,但要执行以下操作:在更高效的环境中处理自身。

没有区别,因为len()是一个非常便宜的操作,您可以轻松地检查它:

# processing the elements of the list:

some_list = [1,4,2,5]

for elem1 in some_list:
    for elem2 in some_list:
        print(elem1+elem2)

当然,在第二个片段中,您没有将两个元素添加在一起这一事实将产生影响:)这两个片段的工作方式不同,因此比较它们没有意义。尝试一下并告诉我们:)运行两个变体,只需使用更大的列表,计时,并告诉我们结果您无法感受到您案例中的速度差异!此外,这里还有两件奇怪的事情:您命名列表
list
,并且您不获取该索引的值,您只处理索引。通常,如果您在列表上进行迭代,则对列表中的元素执行
:更有效、更惯用:您不应将
list
用作变量名:它将隐藏
list
类,阻止您调用
list
构造函数(用于强制转换)扩展
列表
类。您的陈述不正确。在第一个代码片段中计算长度O(n)次,在第二个代码片段中计算长度O(1)次。请注意,当我们为
循环输入一个
时,
范围(..)
只构造了一次。@WillemVanOnsem你怎么能说对于列表中的百万个数字,它在o(1)中计算列表的长度,你知道python的内部是如何计算列表的长度的吗?是的,它只存储元素的数量。请参阅。此外,请不要使用时间<代码>时间
测量的是墙时间,而不是用户时间。@WillemVanOnsem Cool stuff python中的这种深度有什么链接或注释需要了解吗?此外,将
len
的结果存储在外部变量中是容易出错的,也是不可靠的。它增加了代码复杂性和认知开销,但没有任何好处。程序员必须记住,对列表的任何修改都可能使缓存的长度过时。对于如何命名这样一个缓存的
len()
变量,没有真正的约定,为理解代码添加了另一个间接层,更不用说添加了额外的代码行。缓存
len
充其量是一个讨厌的bug,最坏的情况是。
# processing the elements of the list:

some_list = [1,4,2,5]

for elem1 in some_list:
    for elem2 in some_list:
        print(elem1+elem2)
$ cat code1.py 
#!/usr/bin/env python3

for x in range(10000):
    list=[1,2,3,4,5]
    for i in range(len(list)):
        for j in range(len(list)):
            print(i+j)

$ cat code2.py 
#!/usr/bin/env python3

for x in range(10000):
    list=[1,2,3,4,5]
    l=len(list)
    for i in range(l):
        for j in range(l):
            print(i)

$ time ./code1.py >> /dev/null 

real    0m0.153s
user    0m0.152s
sys 0m0.000s

$ time ./code2.py >> /dev/null 

real    0m0.156s
user    0m0.152s
sys 0m0.000s