3

I'm trying to use the map Python function (I know I can use list comprehension but I was instructed to use map in this example) to take the row average of a two row matrix.

Here is what I think the answer should look like:

def average_rows2(mat):
    print( map( float(sum) / len , [mat[0],mat[1]] ) )
average_rows2([[4, 5, 2, 8], [3, 9, 6, 7]])

Right now, only the sum function works:

def average_rows2(mat):
    print( map( sum , [mat[0],mat[1]] ) )
average_rows2([[4, 5, 2, 8], [3, 9, 6, 7]])

The first problem is that adding the float() to the sum function gives the error:

TypeError: float() argument must be a string or a number

Which is weird because the elements of the resulting list should be integers since it successfully calculates the sum.

Also, adding / len to the sum function gives this error:

TypeError: unsupported operand type(s) for /: 'builtin_function_or_method' and 'builtin_function_or_method'

For this error, I tried * and // and it says that none are supported operand types. I don't understand why none of these would be supported.

Maybe this means that the map function doesn't take composite functions?

0

3 Answers 3

8

The first argument has to be evaluated before it can be passed to map. This:

float(sum) / len

is causing you various errors as it doesn't make any sense to evaluate it on its own (unless you'd shadowed sum and len, which would be a different problem). You are trying to sum over one built-in function then divide by another! It therefore cannot be an argument.

Instead, make a function, e.g.:

lambda lst: float(sum(lst)) / len(lst)

This is a callable with a single argument, therefore can be used as the first argument to map, which will then apply it to each element in its second argument. You could also use a regular function, rather than an anonymous lambda (as now shown in https://stackoverflow.com/a/34831192/3001761).

Sign up to request clarification or add additional context in comments.

Comments

0

This will work regardless of how many rows there are:

def average_rows(m):
    return map(lambda l: sum(l) / float(len(l)), m)
print average_rows([[4, 5, 2, 8], [3, 9, 6, 7]]) # [4.75, 6.25]

The function returns a list that's the result of applying the lambda to each element (row) of m.

The lambda expression lambda l: sum(l) / float(len(l)) is basically a function that takes a list and returns the average of its elements as a float. You could assign it to a variable and call it like a regular function:

avg = lambda l: sum(l) / float(len(l))
print avg([1, 2, 3])

Comments

0

What map does is apply a given function to each element of a list. In your case, I think it's clearer to define this function (to calculate the average of a single row) separately, like so:

def average_of_one_row(r):
    return float(sum(r)) / len(r)

def average_of_each_row(mat):
    return map(average_of_one_row, mat)

print average_of_rows([[4, 5, 2, 8], [3, 9, 6, 7]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.