[Tutor] Converting integers into digit sum (Python 3.3.0)

Steven D'Aprano steve at pearwood.info
Tue Dec 10 15:20:36 CET 2013


On Tue, Dec 10, 2013 at 02:31:55PM +0100, Rafael Knuth wrote:

> > So in Python, we can do this with map. First we define a function to do
> > the transformation, then pass it to map:
> >
> > def transform(n):
> >     return 50 + 2*n

Notice here that transformation function takes *one* value, and 
calculates *one* result.

> > result = map(transform, [1, 2, 3, 4])

And here the map() function takes care of looping through the four items 
in the list, passing them to the transform function, and generating a 
new list in Python 2. In Python 3, it holds off generating the list 
unless you ask.

The call to map is (almost) equivalent to this for-loop:

result = []
for item in [1, 2, 3, 4]:
    tmp = transform(item)
    result.append(tmp)


or to this list comprehension:

result = [transform(item) for item in [1, 2, 3, 4]]

So now you can see three equivalent ways to do more or less the same 
thing. 


> #1 Question
> 
> In which cases should I use a map function instead of a for loop like
> this for example:
> 
> def transform(n, m):
>     for i in range (n, m):
>         print (50 + 2*i)

Use whichever seems best for whatever job you need to do. In the above 
function, you calculate the results you want, and print them, and you 
are done. This is not reusable -- it can only do one thing. The only 
part that you can control is the starting and ending value of the range. 
Everything else is fixed -- the transformation equation is always 50 + 
2*i, the result is always printed.

Are you satisfied with that? Great! Then the above is fine.

But if you need more control over what gets done -- perhaps you want to 
change the equation, perhaps you want to save the results in a list 
instead of print them -- then you should look at using map, or a list 
comprehension, instead.


> #2 Question
> 
> Strangely, I get entirely different results depending on whether I use
> return or print within a function.

Not strangely at all. Remember, "return" returns a result back to the 
caller. Once you reach a return line, the function is done and nothing 
else gets calculated, control jumps back to whatever called the 
function.


> Example:
> 
> def transform(n, m):
>     for i in range (n, m):
>         print (50 + 2*i)

Since print does not exit the function, after printing the first value, 
the loop continues, the second value is printed, then the third, and so 
on.

> def transform(n, m):
>     for i in range(n, m):
>         return (50 + 2*i)

Since return exits the function, after the first value is calculated, it 
is returned, and no more values are calculated.

What happens when the result is returned?

Normally, you would assign it to a variable, for later use:

x = transform(1, 5)
# now x == 52

Or perhaps put it in a list:

mylist = []
mylist.append(transform(1, 5)


Or something, anything. The choices are endless: write it to a file, 
pass it to another function, put it in a tuple, a set, a dict or a 
class, turn it into a string, compare it to another result... even print 
it!

What happens if you don't assign it to anything? That depends. In a 
script, Python just ignores the value, and it goes away. In the 
interactive interpreter, Python prints it, as a convenience. You can 
think of the interactive interpreter as treating lines like:

some_function(x, y, z)

as if you wrote something quite similar to:

print( repr(some_function(x, y, z)) )

This is just a convenience for interactive work, and does not apply when 
running as a script.

> Why do I get entirely different results in each case? &:
> How do I prevent my loop from breaking after the first round when
> using return instead of print?

Move the return outside of the loop. First you have to accumulate the 
results somewhere, then only when the loop is finished, return them.

def transform(n, m):
    results = []
    for i in range(n, m):
        results.append(50 + 2*i)
    return results


But you know what? That can be written much more cleanly as:

def transform(n, m):
    return [50 + 2*i for i in range(n, m)]



-- 
Steven


More information about the Tutor mailing list