Reputation: 383
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?
Upvotes: 3
Views: 802
Reputation: 122169
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).
Upvotes: 8
Reputation: 486
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]])
Upvotes: 0
Reputation: 18643
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])
Upvotes: 0