Is using __add__ in Python on an int a bad idea?
I'm looking to increment a value by one and Python does not have the ++ operator. Consider the following example:
# In a method called calculate(self, basecost, othertaxes=None)
# Returns the value of the tax (self) applied to basecost in relation to previous taxes
i = -1
basecost += sum((tax.calculate(basecost, othertaxes[:i.__add__(1)]) for tax in othertaxes))
Is the use of __add__ in this example a bad idea? Is there a better way to write this statement?
Cheers - D
UPDATE
I have changed the answer because the for ... in ...: v += calc solution is much faster than the sum() method. 6 seconds faster over 10000 iterations given my setup but the performance difference is there. Bellow is my test setup:
class Tax(object):
def __init__(self, rate):
self.rate = rat开发者_运维知识库e
def calculate_inline(self, cost, other=[]):
cost += sum((o.calculate(cost, other[:i]) for i, o in enumerate(other)))
return cost * self.rate
def calculate_forloop(self, cost, other=[]):
for i, o in enumerate(other):
cost += o.calculate(cost, other[:i])
return cost * self.rate
def test():
tax1 = Tax(0.1)
tax2 = Tax(0.2)
tax3 = Tax(0.3)
Tax.calculate = calculate_inline # or calculate_forloop
tax1.calculate(100.0, [tax2, tax3])
if __name__ == '__main__':
from timeit import Timer
t = Timer('test()', 'from __main__ import test; gc.enable()')
print t.timeit()
With Tax.calculate = calculate_inline
, the problem took 16.9 seconds, with calculate_forloop
, it took 10.4 seconds.
Seems to be this:
basecost += sum((tax.calculate(basecost, othertaxes[:i])
for i,tax in enumerate(othertaxes))
If I'm reading that right:
for i,tax in enumerate(othertaxes):
basecost += tax.calculate(basecost,othertaxes[:i])
In Python, integers are not mutable (neither are floats, booleans or strings).
You cannot change the value of i unless you write i += 1. i.add(1) does not change the value of i, it just returns a new integer which equals (i+1).
You would normally do a lambda x: x+1
instead of using __add__
精彩评论