创建列表时,为什么+运算符比append()慢得多?

时间:2019-02-06 20:40:44

标签: python python-3.x

(我一开始就把这个问题弄糊涂了,很抱歉,哈哈一整天。) 我几乎是一个初学者,学习使用 thinkpython pdf在python中进行编码。提出的问题之一是编写一个使用appendt = t+[x]构建单词列表的函数。根据我的结果,append的速度明显更快,但是我不知道为什么。

import time

def appended_list():
    fin = open('C:\\Users\\Grim\\Documents\\Python\\\Docs\\words.txt','r')
    wordlist=[]
    for line in fin:
        word = line.strip()
        wordlist.append(word)
    return wordlist


def added_list():
    fin = open('C:\\Users\\Grim\\Documents\\Python\\\Docs\\words.txt','r')
    wordlist=[]
    for line in fin:
        word = line.strip()
        wordlist= wordlist + [word]
    return wordlist

start_t = time.time()
print(len(appended_list()))
end_t = time.time() - start_t
print(end_t)

start_t = time.time()
print(len(added_list()))
end_t = time.time() - start_t
print(end_t)

这是打印出来的内容:

113809
0.1512610912322998
113809
40.448301792144775

3 个答案:

答案 0 :(得分:5)

使用+运算符时,您是在连接原始列表和另一个一元列表({{1 }}(如果您是这种情况),还需要付出额外的努力才能将所有元素从原始列表复制到新分配的列表中。在循环内部,这最终导致[word]的时间复杂度!

通过比较,O(n^2) 通过向现有列表添加新元素来修改,这更便宜并且使用了les内存,因为在后台,该列表已经分配了更多空间超出了容纳当前元素数量所需的数量,只有在元素满时,它才会实际增长到新的大小,并且还有剩余空间。在循环内部,这是append()的摊销时间复杂度,比我们使用O(n)获得的O(n^2)好。

答案 1 :(得分:1)

调用__add__使用的+时,要添加的两个对象必须是相同的type。想想'a' + 1,那会引起TypeError,因为它们不是同一回事。

对于list__add__将需要确保您添加到list的任何内容也是list类型的。这样,cls.__add__(obj)将迫使obj = [obj]出现以促进两个相似对象的添加。这将创建一个新列表,并且附加了内存开销。

但是,append有效地调用了self[len(self):] = obj。这只会修改原始类,而不会因实例化新的list而受到任何惩罚。

答案 2 :(得分:0)

+ 操作将另一个元素添加到原始数组。 追加操作会将数组或对象插入原始数组的末尾,从而导致追加使用更少的内存。