优化字典循环求和值

时间:2018-12-31 20:30:23

标签: python algorithm performance optimization python-2.x

我有一个采用嵌套字典input_dict

的方法
final = 0
for key, value in input_dict[self.state][self.city].iteritems():
    age = self._get_age(key)
    if (age > 0 and age < MAX_VAL):
      final += value  * self.lookup[key][age] * self.multiplier

return final

这大约需要运行0.03秒,但是在一个示例执行中,它被调用了> 10k次,因此最终成为瓶颈,约占运行时间的50%。假设我无法减少调用该方法的总次数,是否有人对如何改进此方法有建议?

2 个答案:

答案 0 :(得分:0)

built-in sum function通常比写出for循环要快。 (请参阅this question。)在您的情况下,您可以构造要求和的值的generator expression,然后将其传递给sum

items = (
    (key,value,self._get_age(key))
    for key,value in input_dict[self.state][self.city].iteritems()
)
return sum(
    value * self.lookup[key][age] * self.multiplier
    for key,value,age in items
    if 0 < age < MAX_VAL
)

答案 1 :(得分:0)

也许考虑以下内容-

current_period = self.current_period - (self.current_period % 7)
MIN_VALUE = current_period - 7 * MAX_VALUE
return self.multiplier * sum(value * self.lookup[key][self._get_age(key)]
    for key, value in input_dict[self.state][self.city].iteritems()
    if MIN_VALUE < key < current_period
)

在这里,我将乘以self.multiplier的乘法从循环中取出,并将比较0 < age < MAX_VALUE替换为等效的预先计算值比较,该比较是通过将age替换为您的{{1}注释中描述的}方法,并解决_get_age()。这样,在key的情况下,我们可以跳过函数调用+额外的计算,并且与原始age <= 0 or age >= MAX_VALUE相比,不会产生任何额外的开销(节省了循环之外的两个变量的计算)。此外,这使我们能够使用内置的0 < age < MAX_VALUE函数,该函数通常比通过for循环求和要快,但不会像qxz的答案那样创建单独的生成器。

请注意,我假设您的sum()方法中的(self.current_period - period)是整数,因此_get_age()将结果放入Python-2.x。如果不是这种情况,请从/ 7分配中删除- (self.current_period % 7),以实现等效功能。