为什么在for循环中使用列表推导式比使用+=执行时间更长?

3
举一个例子,为什么使用列表推导式来计算列表中整数的和时所用时间比正常的for循环更长呢?
class Store:
    def __init__(self, name):
        self.name = name
        self.items = []

    def add_items(self, name, price):
        self.items.append({'name':name, 'price': price})

    def stock_price(self):
        return sum([item['price'] for item in self.items])

    def stock_price2(self):
        total = 0
        for item in self.items:
            total += item.get('price')
        return total

store = Store("Jay")
store.add_items("nike", 100)
store.add_items('puma', 200)
print(timeit.Timer(lambda: store.stock_price()).timeit(number=1000))
print(timeit.Timer(lambda: store.stock_price2()).timeit(number=1000))

股票价格的结果为:0.0007737720006844029

股票价格2的结果为:0.0006722800026182085


6
列表推导式版本将创建一个新列表,然后调用一个函数;如果你实际上不需要这个新列表,那么使用一个简单的循环会更快。 - jonrsharpe
2
尝试使用一个不仅包含一个项目而是一千个项目的列表,并发布结果。我敢打赌列表推导式会更快。 - kosnik
感谢@jonrsharpe:使用生成器求和的方法并不比列表推导式更快。可以在这里找到解释:https://dev59.com/WWct5IYBdhLWcg3wmOng#11964478(简而言之:由于额外调用```next()```,生成器可能会变慢) - Eugene Primako
2个回答

1
在第一个函数中,有一个额外的步骤。它首先创建一个列表,然后使用sum将所有元素相加。第二个函数只是遍历这些元素并将它们添加到总和中。

实际上,第一个函数中的额外步骤并不会使其变慢:https://dev59.com/WWct5IYBdhLWcg3wmOng#11964478(我已在1000万个项目上重新检查过)。 - Eugene Primako

0

正如jonrsharpe所建议的那样,列表推导式会创建一个列表副本。 因此,stock_price()实际上是先创建列表的副本,然后再对其进行迭代并计算总和。(请注意,内置的sum函数比for循环更有效率,因为它是用C语言实现的)

另一方面,stock_price2()不会复制列表,这样可以节省大量用于新列表分配的时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接