1

Let's say that I have a function which takes 10 arguments and another functions which takes 11 arguments and the second one is calling the first one. My code:

def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10

def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11):
    return a11 + func10(a1=a1, a2=a2, a3=a3, a4=a4, a5=a5, a6=a6, a7=a7, a8=a8, a9=a9, a10=a10)

Is it possible to write it nicer, i.e. without writing a1=a1, a2=a2, ...?

EDIT Maybe to be more precise: in the function func11 the arguments are a1, a2, ... a11. Ten of these arguments are also passed to func10 function with exactly the same names. I would like to make this works:

def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11):
    return a11 + func10(arguments)

func11(a1=a1, a11=11, a2=a2, a3=a3, a4=a4, a5=a5, a6=a6, a7=a7, a8=a8, a9=a9, a10=10)

so that I can change the order of arguments when calling func11 but the proper arguments (i.e. a1 - a10) should be passed to func10 inside func11 in a simple way instead of writing again a1=a1 .... How can I do that? And I don't want to do summation in my function, this is just an example!

Jason
  • 313
  • 2
  • 8
  • Your parameters correspond to the position, so you only need to use the form of position parameters: `func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)`. – Mechanic Pig Jun 26 '22 at 14:35
  • 2
    You might want to take a look at [this post](https://stackoverflow.com/questions/3394835/use-of-args-and-kwargs) – Queuebee Jun 26 '22 at 14:36

7 Answers7

0

You don’t need the equals sign and the extra

You can just call it like this:

def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11):
    return a11 + func10(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)

As far as I know you only need argname=object when you use kwargs or a single kwarg.

Update: to match the questions update.

You can define function 11 with kwargs and then pass them on.

def func11(**kwargs):
   return kwargs['a11'] + func10(kwargs['a1'],kwargs['a2'], etc.)
#this let’s you change the position how you want ;)
0

You don't need to explicitly state a1=a1 for every argument func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) will do the same although you most likely should consider using *args or **kwargs for something like this. Example:

def func10(*args):
    total = 0
    for num in args:
        total += num
    return num

Edit: To clarify this would only work if you intended on doing something similar with each argument

Check @MatsLindh answer I think its the best for your scenario if your doing anything more advanced than the solution I suggested (which is likely)

Stelath
  • 11
  • 4
0
"""
The following takes advantage of un-packing in function 11.

Receive 10 arguments in func10 pass the 10 arguments to func11 
in a different order plus one additional argument.

"""

def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
    print('func10 original order  ',[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] )
    a11 = 5
    # Pass original arguments to func11 in different order
    for_func11 = [a3, a2, a1, a4, a6, a5, a7, a8, a11, a10,a9]
    func11(*for_func11)
       
    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10

def func11(b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11):
    print('func11 parameter values',list((b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11)))
    return b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11


func10(1, 2, 3, 4, 6, 7, 8, 9, 10, 11)

output


func10 original order   [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]
func11 parameter values [3, 2, 1, 4, 7, 6, 8, 9, 5, 11, 10]
Carl_M
  • 861
  • 1
  • 7
  • 14
0

Define your functions to instead take a list of arguments for a1-a10 then specify a11 as a keyword argument:

def func10(*args):
    return sum(args)

def func11(*args, **kwargs):
    return kwargs['a11'] + func10(*args)

print(func11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a11=11))
# Outputs 66

Note: This assume a11 exists.

0x263A
  • 1,807
  • 9
  • 22
0

In python you can use *args and **kwargs to pass arguments to a function. Here's some examples on how you could use them:

using args only

def func10(*args):
    return sum(args)

def func11(*args):
    return args[-1] + func10(*args[:-1])

the_args = [1,2,3,4,5,6,7,8,9,10,42]
print(func11(*the_args))

using kwargs and ignoring a11

def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, **ignored_kwargs):
    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10

def func11(**kwargs):
    return kwargs['a11'] + func10(**kwargs)

the_kwargs = dict(a1=1, a2=2, a3=3, a4=4, a5=5, a6=6, a7=7, a8=8, a9=9, a10=10, a11=42)
print(func11(**the_kwargs))

using kwargs values assuming order is correct as args

def func10(*args):
    return sum(args[:-1])

def func11(**kwargs):
    return kwargs['a11'] + func10(*kwargs.values())

the_kwargs = dict(a1=1, a2=2, a3=3, a4=4, a5=5, a6=6, a7=7, a8=8, a9=9, a10=10, a11=42)
print(func11(**the_kwargs))
Queuebee
  • 651
  • 1
  • 6
  • 24
0
def func10(data):
    return sum(data)
    
    
def func11(data):
    return data[10] + func10(data[:10:])
    
    
def main():
    a1 = 1
    a2 = 2
    a3 = 3
    a4 = 4
    a5 = 5
    a6 = 6
    a7 = 7
    a8 = 8
    a9 = 9
    a10 = 10
    a11 = 11
    print(func11([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11]))

main()

Based on your edit you can change the order of the arguments inside the list for the initial func11 call.

Hakro
  • 2,625
  • 1
  • 12
  • 23
Ftoy
  • 26
  • 6
-1

You can do a bit of trickery by using locals() as the first statement inside your function, effectively capturing all the arguments given to the function and their values. You can then use **kwargs to pass these on to the previous function - but you need to remove a11 first, since func10 doesn't know anything about it.

def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10):
    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10


def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11):
    given_args = locals()
    del given_args['a11']
    
    return func10(**given_args) + a11
    
    
print(func10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
print(func11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))

Output:

55
66

However, if this is something you see yourself having to do a lot, you might want to define a1, a2 etc. as properties of a Pydantic model instead, and then let each step populate another value in that model.

MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • 2
    There really isn't a good reason to use `locals()` here. – ndc85430 Jun 26 '22 at 14:43
  • 1
    @ndc85430 That really depends on the _actual_ use case of OP. If you want to dynamically capture everything given to the function to pass it on to another function, without specifying each argument (which seems to be what OP is asking about), then that's at least one way to do it. If the goal is to be explicit, OP has already posted the answer to that in the question. Feel free to argue why you feel that `locals()` isn't a good solution for that interpretation. – MatsLindh Jun 26 '22 at 14:46