The task is to multiply items in some iterable by three.
multipled = [3 * s for s in series]
One list comprehension later, the task is complete.
Next, we find out that we need to count how many multiplications are
performed. len()
is forbidden, because we are dealing with iterators
(and inevitably the itertools
module). One solution is to create a CallCounting
class that wraps
callables.
class CallCounting(object):
def __init__(self, func):
self.count = 0
self.func = func
def __call__(self, *args, **kwargs):
self.count += 1
return self.func(*args, **kwargs)
timesthree = CallCounting(lambda x: 3 * x)
multipled = [timesthree(n) for n in series]
print "%d calls" % timesthree.count
This is efficient as well as readable. The main action is to multiply items. We keep a call count just for bookkeeping. Compare with
calls = 0
multipled = []
for n in series:
calls += 1
multipled.append(3 * n)
print "%d calls" % calls
that is both ugly and inefficient.