7

I was asked to write a function in Python 3 for: Write a function called general_poly, that would, for example, evaluate general_poly([1, 2, 3, 4])(10) to 1234 because 1*10^3 + 2*10^2 + 3*10^1 + 4*10^0.

Now I don't understand what the second parenthesis, (10), means.

How would my function general_poly know, to take that value inside itself and use it?

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
ccasimiro9444
  • 425
  • 1
  • 6
  • 22
  • 5
    it means that the function wil return function and the returned function will becalled with 10 as argument. So your general_poly shod return function which will use 10 as a base. https://stackoverflow.com/questions/42874825/python-functions-with-multiple-parameter-brackets – Josef Prochazka May 04 '18 at 08:39

3 Answers3

11

It means that your function should return a function:

def multiplier(times):
    def inner(num):
         return num * times
    return inner

result = multiplier(2)(3)
print(result)
# 6

times_four = multiplier(4)
print(times_four(3))
# 12

This may or may not be an overkill, but if you need to save state you can even use a class and implement __call__:

class multiplier:
    def __init__(self, times):
        self.times = times
    def __call__(self, num):
        return num * self.times

print(multiplier(2)(3))
# 6
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • Ah, now I understand, it returns a function without the parenthesis and then uses the second parenthesis as input. Thank you very much – ccasimiro9444 May 04 '18 at 08:38
2

A function is a first-class object in Python. One of the corollaries of this is that a function may return another function.

Your particular example can be written as follows:

def general_poly(A):
    k = len(A)
    def power(n):
        return sum(j*n**(k-i) for i, j in enumerate(A, 1))
    return power

res = general_poly([1, 2, 3, 4])(10)  # 1234

The outer function general_poly returns the inner function power. The former takes a list, or an array, while the latter takes a scalar.


An alternative way of structuring your logic is to use functools.partial. This creates a new function which one or more parameters fixed and obviates the need for an inner function.

from functools import partial

def general_poly(A, n):
    k = len(A)
    return sum(j*10**(k-i) for i, j in enumerate(A, 1))

genral_poly_10 = partial(general_poly, n=10)
res = genral_poly_10([1, 2, 3, 4])  # 1234

Of course, this is only useful if you wish to create a function for a specific power; trivially, n can be used directly as an additional parameter without functools.partial.


Note: Beware of mutable default arguments. So if your function has a mutable default argument, e.g. setting A=[] in the above examples, the same list may be reused in an unforeseen way.

jpp
  • 159,742
  • 34
  • 281
  • 339
1

The second set of paranthesis don't actually interact with the function, they apply to whatever the function returns. It's the same principle as returnsAList()[0], which would give you the first element of the list returned by returnsAList().

BurnNote
  • 405
  • 1
  • 4
  • 13