# Iterating a function with a static argument: Global functions + lambdas vs internal function?

I am never sure which of these is better form:

Option A

``````def a(x,y):
def b(z): return z+y
return map(b, x)
print a([10,20], 5)
``````

Option B

``````def b(z,y): return z+y
def a(x,y):
return map(lambda x: b(x,y), x)
print a([10,20], 5)
``````

Suppose that b() is ONLY ever called from inside a().

I know Option B is more efficient because it only declares b() once, and then the variable y is just passed as a context variable. But Option A seems to be simpler syntax, eliminating the need to construct a lambda, and simplifying the interface of b(). Suppose further that there could actually be many context arguments. The complexity blows up on the interface of b():

Option A2:

``````def a(x,y1,y2,y3,y4,y5):
def b(z): return z+y1+y2+y3+y4+y5
return map(b, x)
print a([10,20], 5,6,7,8,9)
``````

Option B2:

``````def b(z,y1,y2,y3,y4,y5): return z+y1+y2+y3+y4+y5
def a(x,y1,y2,y3,y4,y5):
return map(lambda x: b(x,y1,y2,y3,y4,y5), x)
print a([10,20], 5,6,7,8,9)
``````

Option A2 is far fewer characters. Thoughts?

• Care about efficiency when it's on your performance-critical path, and you have profiling results that confirm it. Otherwise, go for simplicity; programmers' time costs much more than CPU time.
– 9000
Feb 1, 2015 at 19:58
• The `b` in your Option Bs doesn't seem to have much point. Why not just do `map (lambda x:x+y1+y2+y3+y4+y5, x)` for B2 for instance? In general, I'd only ever use a lambda, or define a function, but never both in conjunction. Feb 1, 2015 at 22:05

Per the Zen of Python: simple is always better than complex. I'd pick the first option on the principle that it is vastly easier to understand and thus easier to maintain. Generally speaking, in Python, one worries more about the ease of use of the code than the efficiency of the code.

If you want to simplify long lists of arguments, use *args:

4.7.3. Arbitrary Argument Lists

Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see Tuples and Sequences). Before the variable number of arguments, zero or more normal arguments may occur.

``````def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
``````

Normally, these variadic arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.

``````>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
``````
• When would a lambda expression be appropriate, then? When you want to use the function in more than one place? Feb 1, 2015 at 19:49
• you could use a lambda in place of b in example 1 as well. b isn't even really necessary. This is perfectly valid: def a(x, y): return map(lambda z: z+y, x)
– user28988
Feb 1, 2015 at 20:23

Do you need the efficiency more than the simplicity, or the simplicity more than the efficiency?

Use what makes sense for your specific application. If you need the simplicity more than the efficiency, then use option A. If you need the efficiency more than the simplicity, then use option B.

Code profilers can help immensely in this regard. Programmers are notoriously bad at guessing how expensive a given operation is; a code profiler can give you evidence that will help you determine the real cost of a computation, and help you make a better, more informed choice.