Python: Accept multiple arguments - python

In Python I am trying to make a function that can accept 1 or more arguments. For simplicity let's say I want to make a function that prints all the arguments that are passed
def print_all(**arguments**):
print(arg1, arg2, ..., argN)
so print_all("A", "B") would output AB.
The number of arguments passed could be 1 or more strings.
What is the best way to do this?

*args and **kwargs allow to pass any no of arguments, positional (*) and keyword (**) to the function
>>> def test(*args):
... for var in args:
... print var
...
>>>
For no of variable
>>> test("a",1,"b",2)
a
1
b
2
>>> test(1,2,3)
1
2
3
For list & dict
>>> a = [1,2,3,4,5,6]
>>> test(a)
[1, 2, 3, 4, 5, 6]
>>> b = {'a':1,'b':2,'c':3}
>>> test(b)
{'a': 1, 'c': 3, 'b': 2}
For detail

Simply this:
def print_all(*args):
for arg in args:
print(arg)

Use the splat operator (*) to pass one or more positional arguments. Then join them as strings in your function to print the result.
def print_all(*args):
print("".join(str(a) for a in args))
>>> print_all(1, 2, 3, 'a')
123a

You are looking for the usage of *args which allows you to pass multiple arguments to function without caring about the number of arguments you want to pass.
Sample example:
>>> def arg_funct(*args):
... print args
...
>>> arg_funct('A', 'B', 'C')
('A', 'B', 'C')
>>> arg_funct('A')
('A',)
Here this function is returning the tuple of parameters passed to your function.
For more details, check: What does ** (double star) and * (star) do for parameters?

Related

*_ and *args assigns which value at runtime | python |

Not getting internally what is happening. *_ amd *args doing
what is assigned to default() at runtime
Using *_ in default
def default(*_):
return "Not Happy"
a,b=10,20
default(a,b)
Using *args in default
def default(*args):
return "Not Happy"
a,b=10,20
default(a,b)
I am trying to understand what is assigned to default at runtime.
if not a and b
I have used website to see visually what happens at runtime during execution but not getting : https://pythontutor.com/visualize.html
In Python, you can define variadic functions (i.e. functions that can take any number of arguments), cf the tutorial or a RealPython article about it.
The gist of it is that you can declare a *whatever parameter, and Python will collect the variadic parameters and put them in there for you. For example :
>>> def foo(*args):
>>> print(type(args), args)
>>>
>>> foo()
<class 'tuple'> ()
>>> foo(1)
<class 'tuple'> (1,)
>>> foo(1, 'a')
<class 'tuple'> (1, 'a')
>>> foo(1, 'a', 'b', 'c')
<class 'tuple'> (1, 'a', 'b', 'c')
The convention is to call it args, but you can give it another name :
>>> def foo(*elephant):
>>> print(elephant)
>>>
>>> foo(1, 'a')
(1, 'a')
So when you call default(a,b), then *args (or *_ if you want) is filled, and you can use it in your function :
>>> def default(*args):
>>> return "Not Happy" + str(args)
>>>
>>> a,b=10,20
>>> default(a,b)
'Not Happy(10, 20)'
default is a function, when you do default(...) you call that function, meaning you execute the code you wrote in it. You are passing a and b, none of them is listed as a regular parameter, so both ends up in the *args parameter.

passing a tuple in *args

I'd like to pass a tuple (or maybe a list) to a function as a sequence of values (arguments). The tuple should be then unpacked as an argument into *arg.
For example, this is clear:
def func(*args):
for i in args:
print "i = ", i
func('a', 'b', 3, 'something')
But what I want to do is this:
tup = ('a1', 'a2', 4, 'something-else')
func(tup)
And this should behave similar to the first case.
I think I should use here reprint and eval but not sure how exactly.
I know that I can just pass the tuple in the function and then unpack it within the body, but my question here is how to unpack it in the function call itself.
You can just use func(*tup) to unpack the tuple directly when you invoke the function.
>>> func(*tup)
i = a1
i = a2
i = 4
i = something-else
This is kind of equivalent to func(tup[0], tup[1], tup[2], ...). The same also works if the function expects multiple individual parameters:
>>> def func2(a, b, c, d):
... print(a, b, c, d)
...
>>> func2(*tup)
('a1', 'a2', 4, 'something-else')
See e.g. here for more in-depth background on the syntax.
You can unpack the tuple during the call by putting a * before the identifier of the tuple. This allows you to easily differentiate between tuples that should be unpacked and ones which shouldn't. This is an example:
>>> MyTuple = ('one', 2, [3])
>>>
>>> def func(*args):
... for arg in args:
... print(arg)
...
>>>
>>> func(*MyTuple)
one
2
[3]
>>>
>>> func(MyTuple)
('one', 2, [3])
You can use *args if you want to unpack your tuple.
Your method definition goes as follows :
def func(*tup):
for i in tup:
print(print "i = ",i)
Now calling your method:
tup = ('a1','a1',4,'something-else')
func(*tup)
Which will yield you the output as-
i = a1
i = a2
i = 4
i = something-else

Passing several arguments from an array to a function in a easy way

Well I really don't know how to describe this in words but I've an easy example:
def foo(x,y,z):
r=x+....
a = [1,2,3]
foo(a[0], a[1], a[2])
Can I do the same without calling a[n] several times? but keeping "x,y,z" definition?
Use the unpacking operator!
>>> def foo(x,y,z):
... return x+y+z
...
>>> a = [1,2,3]
>>> foo(*a)
6
From the documentation
If they are not available separately, write the function call with the
*-operator to unpack the arguments out of a list or tuple:
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list [3, 4, 5]
Yeah use unpacking operator to pass any arbitrary arguments to your function :
def foo(*args):
for i in args : # you can iterate over args or get its elements by indexing
#do stuff
a = [1,2,3]
foo(*a)
And if you just pass 3 argument you can use unpacking in call time.
def foo(x,y,z):
r=x+....
a = [1,2,3]
foo(*a)
Try this
def foo(x,y,z):
r=x+....
a = [1,2,3]
foo(*a)

Is there a more pythonic way of exploding a list over a function's arguments?

def foo(a, b, c):
print a+b+c
i = [1,2,3]
Is there a way to call foo(i) without explicit indexing on i?
Trying to avoid foo(i[0], i[1], i[2])
Yes, use foo(*i):
>>> foo(*i)
6
You can also use * in function definition:
def foo(*vargs) puts all non-keyword arguments into a tuple called vargs.
and the use of **, for eg., def foo(**kargs), will put all keyword arguments into a dictionary called kargs:
>>> def foo(*vargs, **kargs):
print vargs
print kargs
>>> foo(1, 2, 3, a="A", b="B")
(1, 2, 3)
{'a': 'A', 'b': 'B'}
It's called argument unpacking and there's an operator for it.
foo(*i)
By the way, it works with any iterable, not just with lists.
Yes, Python supports that:
foo(*i)
See the documentation on Unpacking Argument Lists. Works with anything iterable. With two stars ** it works for dicts and named arguments.
def bar(a, b, c):
return a * b * c
j = {'a': 5, 'b': 3, 'c': 2}
bar(**j)

Find out the number of arguments passed to a function consisting of default values for arguments in python

Consider the following python function:
def fun(x=0,y=1,z=1):
print x,y,z
fun(2)
Is there a way i can find out within the function how many arguments were actually passed to it,which in the above case is 1 ?
Please Help
Thank You
Have a look at the inspect module
import inspect
inspect.getargspec(someMethod)
Get the names and default values of a Python function’s arguments. A tuple of four things is returned: (args, varargs, keywords, defaults). args is a list of the argument names (it may contain nested lists). varargs and keywords are the names of the * and ** arguments or None. defaults is a tuple of default argument values or None if there are no default arguments; if this tuple has n elements, they correspond to the last n elements listed in args.
>>> def fun(x=0,y=1,z=1):
... print x,y,z
...
>>> func = fun
>>> func.func_code.co_argcount
3
>>> func.func_code.co_varnames
('x', 'y', 'z')
You can also try inspect module
>>> import inspect
>>> inspect.getargspec(func).args
['x', 'y', 'z']
>>> inspect.getargspec(func)
ArgSpec(args=['x', 'y', 'z'], varargs=None, keywords=None, defaults=(0, 1, 1))
Are you looking something like:
def fun(**kwargs):
arg_count = len(kwargs)
print("Function called with",arg_count,"arguments")
params = {"x": 0, "y": 1, "z":1} #defaults
params.update(kwargs)
print("Now arguments are", params, )
fun(x=2)
Output:
Function called with 1 arguments
Now arguments are {'y': 1, 'x': 2, 'z': 1}

Categories

Resources