Incomprehensible syntax in Python - passing variables as arguments - python

I cannot find anywhere why to use and if are there any diffrences between these 2 calls:
someFunction(10)
and
someFunction(x=10)

Your initial invocation of the function is using a positional argument - that is, it will match the '10' with the first parameter of the argument.
However, if you explicitly call the function with a keyword argument, it will match the value with the specified keyword.
def kwarg_func(x = 5, y = 10, z = 2):
return x * y * z
# will return 200 (10 * 10 * 2)
print(kwarg_func(10))
# will return 10 (5 * 1 * 2)
print(kwarg_func(y = 1))
# will throw an error since keyword 'a' is undefined
print(kwarg_func(a = 1))

So the reason you'd really be passing x=10, is if it was a **kwarg or if x is set in the variable
def somefunction(x=5):
print(x*x)
somefunction(x=10)
That would result in 10*10, thus 100.
The reason behind this is that Python accepts positional arguments which are effectively:
def somefunction(x)
#dosomestuff
Where x in somefunction is in position 0 for the arguments you can pass to it.
Where as:
def somefunction(x=10)
#dosomestuff
Is a keyword argument (but you can use its position as well)
A positional argument must be before a keyword argument.
The python tutorial has a good touch on this: https://docs.python.org/3/tutorial/controlflow.html#defining-functions

Your question is a bit vague and it depends on your function construction.
Suppose, you have a function:
def someFunction(x):
return x
Then you can call it via someFunction(10) or someFunction(x=10) while the latter is more verbose but the first will totally suffice. Look up args and **kwargs for a better understanding, e.g. here.

there is a major importance of args and kwargs. first of all 10 is the arg(argument) and x=10(keyword argument) is called kwarg.
the most basic difference between these two is args are taken in order and kwargs are not.
kwargs can be given in any order.
before reading this answer I hope you have some knowledge on python default arguments.
def func(a=25, b, c, d=3, e, f=2, g, h=1, i):
return a * b * c * d * e * f * g * h * i
in this function, you can pass all the arguments or you can pass only essential arguments
essential arguments are b, c, e, g, i
and default arguments are a, d, f, h.
So the question becomes how to pass values only for essential arguments.
the answer is kwargs. since for kwargs, there is no importance of the order we can pass the arguments as func(b=3, c=4, e=2, g=10) or func(c=4, g=10, b=3, e=2) any combination would work for this.

Related

Optional arguments in nested functions in Python

Is it possible for one function to take as an argument the name of one of the optional arguments of a second function then call the second function with the optional argument set to the value of some variable in the first function?
Code (that obviously doesn't work)
def foo(a=1,b=2,c=3):
d = a + b + c
return d
def bar(variable):
z = get_user_input()
e = foo(variable = z)
return e
print(bar(a))
The desired result is for bar to call foo(a=z) and print whatever z+2+3 is. Of course Python doesn't know what (a) is here. My guess is that I can somehow reference the list of arguments of foo() , but I am stumped as to how you might do that.
Maybe try the code snippet below
def foo(a=1,b=2,c=3):
d = a + b + c
return d
def bar(variable: str):
z = int(input())
e = foo(**{variable: z})
return e
# variable name should be defined as string
print(bar("a"))
The ** parses all arbitrary arguments on dict, in this case is a. Be careful tho, as if passing wrong variable name (differ from a, b or c) will result raising error.

Python equivalent of R's ... for matching function arguments

Within R, you can use a special argument ... when defining functions, which is described here:
This argument will match any arguments not otherwise matched, and can be easily passed on to other functions. This is useful if you want to collect arguments to call another function, but you don’t want to prespecify their possible names.
This means that if I write a function a that uses another function b within it, I don't need to include all of the possible arguments of b as arguments to a in order to use them.
In Python, is there anything equivalent?
There's no single construct, but a combination of * and ** parameters does the same, I believe.
def g(x, y, z):
return x + y + z
def f(x, *args, **kwargs):
print(x)
print(args)
print(kwargs)
print(g(*args, **kwargs))
f(9, 1, 2, z=3)
produces
9
(1, 2)
{'z': 3}
6
as output.

How can I unpack tuple when other variables are needed?

According to this, I can call a function that takes N arguments with a tuple containing those arguments, with f(*my_tuple).
Is there a way to combine unpacking and unpacked variables?
Something like:
def f(x,y,z):...
a = (1,2)
f(*a, 3)
The code you supplied (f(*a, 3)) is valid for python 3. For python 2, you can create a new tuple by adding in the extra values. Then unpack the new tuple.
For example if you had the following function f:
def f(x, y, z):
return x*y - y*z
print(f(1,2,3))
#-4
Attempting your code results in an error in python 2:
a = (1,2)
print(f(*a,3))
#SyntaxError: only named arguments may follow *expression
So just make a new tuple:
new_a = a + (3,)
print(f(*new_a))
#-4
Update
I should also add another option is to pass in a named argument after the * expression (as stated in the SyntaxError):
print(f(*a, z=3))
#-4
A little heavy, but you can use functools.partial to partially apply f to the arguments in a before calling the resulting callable on 3.
from functools import partial
partial(f, *a)(3)
This is more useful if you plan on making a lot of calls to f with the same two arguments from a, but with different 3rd arguments; for example:
a = (1,2)
g = partial(f, *a)
for k in some_list:
g(k) # Same as f(1,2,k)
as #pault said - you can create a new tuple , and you can do another thing which is:
pass the *a as the last variable to a function, for example :
def f(x,y,z):...
a = (1,2)
f(3, *a)
worked for me in Python 2.7

optional arguments function

I am searching how I could use optional arguments in python.
I have read this question but it is not clear to me.
Lets say I have a function f that can take 1 or more arguments to understand time series. Am i obliged to specify the number of arguments and set default values for each argument?
What I aim to do is being able to write a function this way:
simple function:
def f(x,y):
return x + y
#f(1,2) returns 3
What i want is also f(1,2,3) to return me 6 and f(7) returning me 7
Is it possible to write it without setting a predefined number of mandatory/optional parameters?
Is it possible to write it without having to set default values to 0 ?
How to write this function?
Its a simple example with numbers but the function i need to write is comparing a set of successive objects. After comparison is done, the data set will feed a neural network.
Thanks for reading.
EDIT:
Objects I am feeding my function with are tuples like this (float,float,float,bool,string)
You can put *args in your function and then take arbitrary (non-keyword) arguments. *args is a tuple, so you can iterate over it like any Python tuple/list/iterable. IE:
def f(*args):
theSum = 0
for arg in args:
theSum += arg
return theSum
print f(1,2,3,4)
def f(*args):
"""
>>> f(1, 2)
3
>>> f(7)
7
>>> f(1, 2, 3)
6
>>> f(1, 2, 3, 4, 5, 6)
21
"""
return sum(args)
If you need to do something more complicated than sum you could just iterate over args like this:
def f(*args):
r = 0
for arg in args:
r += arg
return r
See this question for more information on *args and **kwargs
Also see this sections on the Python tutorial: Arbitray Argument List
You can use the follow syntax:
def f(*args):
return sum(args)
The * before args tells it to "swallow up" all arguments, makng args a tuple. You can also mix this form with standard arguments, as long as the *args goes last. For example:
def g(a,b,*args):
return a * b * sum(args)
The first example uses the built-in sum function to total up the arguments. sum takes a sequence as adds it up for you:
>>> sum([1,3,5])
9
>>> sum(range(100))
4950
The args name is not mandatory but is used by convention so best to stick with it. There is also **kwargs for undefined keyword arguments.

What does asterisk * mean in Python? [duplicate]

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 9 years ago.
Does * have a special meaning in Python as it does in C? I saw a function like this in the Python Cookbook:
def get(self, *a, **kw)
Would you please explain it to me or point out where I can find an answer (Google interprets the * as wild card character and thus I cannot find a satisfactory answer).
See Function Definitions in the Language Reference.
If the form *identifier is
present, it is initialized to a tuple
receiving any excess positional
parameters, defaulting to the empty
tuple. If the form **identifier is
present, it is initialized to a new
dictionary receiving any excess
keyword arguments, defaulting to a new
empty dictionary.
Also, see Function Calls.
Assuming that one knows what positional and keyword arguments are, here are some examples:
Example 1:
# Excess keyword argument (python 2) example:
def foo(a, b, c, **args):
print "a = %s" % (a,)
print "b = %s" % (b,)
print "c = %s" % (c,)
print args
foo(a="testa", d="excess", c="testc", b="testb", k="another_excess")
As you can see in the above example, we only have parameters a, b, c in the signature of the foo function. Since d and k are not present, they are put into the args dictionary. The output of the program is:
a = testa
b = testb
c = testc
{'k': 'another_excess', 'd': 'excess'}
Example 2:
# Excess positional argument (python 2) example:
def foo(a, b, c, *args):
print "a = %s" % (a,)
print "b = %s" % (b,)
print "c = %s" % (c,)
print args
foo("testa", "testb", "testc", "excess", "another_excess")
Here, since we're testing positional arguments, the excess ones have to be on the end, and *args packs them into a tuple, so the output of this program is:
a = testa
b = testb
c = testc
('excess', 'another_excess')
You can also unpack a dictionary or a tuple into arguments of a function:
def foo(a,b,c,**args):
print "a=%s" % (a,)
print "b=%s" % (b,)
print "c=%s" % (c,)
print "args=%s" % (args,)
argdict = dict(a="testa", b="testb", c="testc", excessarg="string")
foo(**argdict)
Prints:
a=testa
b=testb
c=testc
args={'excessarg': 'string'}
And
def foo(a,b,c,*args):
print "a=%s" % (a,)
print "b=%s" % (b,)
print "c=%s" % (c,)
print "args=%s" % (args,)
argtuple = ("testa","testb","testc","excess")
foo(*argtuple)
Prints:
a=testa
b=testb
c=testc
args=('excess',)
I only have one thing to add that wasn't clear from the other answers (for completeness's sake).
You may also use the stars when calling the function. For example, say you have code like this:
>>> def foo(*args):
... print(args)
...
>>> l = [1,2,3,4,5]
You can pass the list l into foo like so...
>>> foo(*l)
(1, 2, 3, 4, 5)
You can do the same for dictionaries...
>>> def foo(**argd):
... print(argd)
...
>>> d = {'a' : 'b', 'c' : 'd'}
>>> foo(**d)
{'a': 'b', 'c': 'd'}
All of the above answers were perfectly clear and complete, but just for the record I'd like to confirm that the meaning of * and ** in python has absolutely no similarity with the meaning of similar-looking operators in C.
They are called the argument-unpacking and keyword-argument-unpacking operators.
A single star means that the variable 'a' will be a tuple of extra parameters that were supplied to the function. The double star means the variable 'kw' will be a variable-size dictionary of extra parameters that were supplied with keywords.
Although the actual behavior is spec'd out, it still sometimes can be very non-intuitive. Writing some sample functions and calling them with various parameter styles may help you understand what is allowed and what the results are.
def f0(a)
def f1(*a)
def f2(**a)
def f3(*a, **b)
etc...
I find * useful when writing a function that takes another callback function as a parameter:
def some_function(parm1, parm2, callback, *callback_args):
a = 1
b = 2
...
callback(a, b, *callback_args)
...
That way, callers can pass in arbitrary extra parameters that will be passed through to their callback function. The nice thing is that the callback function can use normal function parameters. That is, it doesn't need to use the * syntax at all. Here's an example:
def my_callback_function(a, b, x, y, z):
...
x = 5
y = 6
z = 7
some_function('parm1', 'parm2', my_callback_function, x, y, z)
Of course, closures provide another way of doing the same thing without requiring you to pass x, y, and z through some_function() and into my_callback_function().

Categories