Custom higher-order functions

Functions like sort, max, or min can take arguments like key= that are functions and can determine their behavior. This makes the built-in functions sort and max way more powerful and generic. They can be used in many more scenarios than if they would only compare the values themselves without the key= argument.
We can create our own higher-order functions as well:
def modify(numbers, f):
	res = [f(n) for n in numbers]
	return res

print(modify([1, 2, 3], lambda x: x**2))   # [1, 4, 9]
print(modify([1, 2, 3], lambda x: -x))     # [-1, -2, -3]
print(modify([2, 0, 1], lambda x: 2 * x))  # [4, 0, 2]
print(modify([2, 0, 1], str))              # ['2', '0', '1']
Here we pass different functions as f to the higher-order function modify. The modify function creates a new list from the input one and returns the result. Note that we can even pass a function like str to the function as well. So, each element of the input list will get applied a str() function - str(2), str(0), str(1).

Challenge

Implement a generic version of the sum function called generic_sum which will take a collection as the first argument (it can be a list, a set, or a list of tuples) and a function as a second argument that obtains a number from each element of the collection.
def generic_sum():
	...

print(generic_sum([1, 2, 3], lambda x: x))                   # 6
print(generic_sum({1, 2, 3}, lambda x: x))                   # 6
print(generic_sum([(1, 3), (4, 6)], lambda x: x[0] + x[1]))  # 14
 

Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB

To check your solution you need to sign in