Can a variable number of arguments be passed to a function? - python

In a similar way to using varargs in C or C++:
fn(a, b)
fn(a, b, c, d, ...)

Yes. You can use *args as a non-keyword argument. You will then be able to pass any number of arguments.
def manyArgs(*arg):
print "I was called with", len(arg), "arguments:", arg
>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)
As you can see, Python will unpack the arguments as a single tuple with all the arguments.
For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.

Adding to unwinds post:
You can send multiple key-value args too.
def myfunc(**kwargs):
# kwargs is a dictionary.
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
And you can mix the two:
def myfunc2(*args, **kwargs):
for a in args:
print a
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123
They must be both declared and called in that order, that is the function signature needs to be *args, **kwargs, and called in that order.

If I may, Skurmedel's code is for python 2; to adapt it to python 3, change iteritems to items and add parenthesis to print. That could prevent beginners like me to bump into:
AttributeError: 'dict' object has no attribute 'iteritems' and search elsewhere (e.g. Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) why this is happening.
def myfunc(**kwargs):
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
and:
def myfunc2(*args, **kwargs):
for a in args:
print(a)
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123

Adding to the other excellent posts.
Sometimes you don't want to specify the number of arguments and want to use keys for them (the compiler will complain if one argument passed in a dictionary is not used in the method).
def manyArgs1(args):
print args.a, args.b #note args.c is not used here
def manyArgs2(args):
print args.c #note args.b and .c are not used here
class Args: pass
args = Args()
args.a = 1
args.b = 2
args.c = 3
manyArgs1(args) #outputs 1 2
manyArgs2(args) #outputs 3
Then you can do things like
myfuns = [manyArgs1, manyArgs2]
for fun in myfuns:
fun(args)

def f(dic):
if 'a' in dic:
print dic['a'],
pass
else: print 'None',
if 'b' in dic:
print dic['b'],
pass
else: print 'None',
if 'c' in dic:
print dic['c'],
pass
else: print 'None',
print
pass
f({})
f({'a':20,
'c':30})
f({'a':20,
'c':30,
'b':'red'})
____________
the above code will output
None None None
20 None 30
20 red 30
This is as good as passing variable arguments by means of a dictionary

Another way to go about it, besides the nice answers already mentioned, depends upon the fact that you can pass optional named arguments by position. For example,
def f(x,y=None):
print(x)
if y is not None:
print(y)
Yields
In [11]: f(1,2)
1
2
In [12]: f(1)
1

Related

How to have function with multiple parameters without having to type every single parameter? [duplicate]

In a similar way to using varargs in C or C++:
fn(a, b)
fn(a, b, c, d, ...)
Yes. You can use *args as a non-keyword argument. You will then be able to pass any number of arguments.
def manyArgs(*arg):
print "I was called with", len(arg), "arguments:", arg
>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)
As you can see, Python will unpack the arguments as a single tuple with all the arguments.
For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.
Adding to unwinds post:
You can send multiple key-value args too.
def myfunc(**kwargs):
# kwargs is a dictionary.
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
And you can mix the two:
def myfunc2(*args, **kwargs):
for a in args:
print a
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123
They must be both declared and called in that order, that is the function signature needs to be *args, **kwargs, and called in that order.
If I may, Skurmedel's code is for python 2; to adapt it to python 3, change iteritems to items and add parenthesis to print. That could prevent beginners like me to bump into:
AttributeError: 'dict' object has no attribute 'iteritems' and search elsewhere (e.g. Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) why this is happening.
def myfunc(**kwargs):
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
and:
def myfunc2(*args, **kwargs):
for a in args:
print(a)
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123
Adding to the other excellent posts.
Sometimes you don't want to specify the number of arguments and want to use keys for them (the compiler will complain if one argument passed in a dictionary is not used in the method).
def manyArgs1(args):
print args.a, args.b #note args.c is not used here
def manyArgs2(args):
print args.c #note args.b and .c are not used here
class Args: pass
args = Args()
args.a = 1
args.b = 2
args.c = 3
manyArgs1(args) #outputs 1 2
manyArgs2(args) #outputs 3
Then you can do things like
myfuns = [manyArgs1, manyArgs2]
for fun in myfuns:
fun(args)
def f(dic):
if 'a' in dic:
print dic['a'],
pass
else: print 'None',
if 'b' in dic:
print dic['b'],
pass
else: print 'None',
if 'c' in dic:
print dic['c'],
pass
else: print 'None',
print
pass
f({})
f({'a':20,
'c':30})
f({'a':20,
'c':30,
'b':'red'})
____________
the above code will output
None None None
20 None 30
20 red 30
This is as good as passing variable arguments by means of a dictionary
Another way to go about it, besides the nice answers already mentioned, depends upon the fact that you can pass optional named arguments by position. For example,
def f(x,y=None):
print(x)
if y is not None:
print(y)
Yields
In [11]: f(1,2)
1
2
In [12]: f(1)
1

Convert varargin and nargin to from Matlab to Python

How would one convert the following Matlab code to Python? Are there equivalent functions to Matlab's varargin and nargin in Python?
function obj = Con(varargin)
if nargin == 0
return
end
numNodes = length(varargin);
obj.node = craft.empty();
obj.node(numNodes,1) = craft();
for n = 1:numNodes
% isa(obj,ClassName) returns true if obj is an instance of
% the class specified by ClassName, and false otherwise.
% varargin is an input variable in a function definition
% statement that enables the function to accept any number
% of input arguments.
if isa(varargin{n},'craft')
obj.node(n) = varargin{n};
else
error(Invalid input for nodes property.');
end
end
end
varargin's equivalent
The *args and **kwargs is a common idiom to allow arbitrary number of arguments to functions. The single asterisk form (*args) is used to pass a non-keyworded, variable-length argument list, and the double asterisk (**kwargs) form is used to pass a keyworded, variable-length argument list.
Here is an example of how to use the non-keyworded form:
>>> def test_args(*args):
... # args is a tuple
... for a in args:
... print(a)
...
>>> test_args(1, 'two', 3)
1
two
3
Here is an example of how to use the keyworded form:
>>> def test_kwargs(**kwargs):
... # kwargs is a dictionary
... for k, v in kwargs.items():
... print('{}: {}'.format(k, v))
...
>>> test_kwargs(foo = 'Hello', bar = 'World')
foo: Hello
bar: World
nargin's equivalent
Since nargin is just the number of function input arguments (i.e., number of mandatory argument + number of optional arguments), you can emulate it with len(args) or len(kwargs).
def foo(x1, x2, *args):
varargin = args
nargin = 2 + len(varargin) # 2 mandatory arguments (x1 and x2)
# ...

What is the proper way to loop through the required keyword arguments of a function and perform the same action on each of their values?

I'm looking to strip the white-space from each of the arguments in a function that takes a bunch of required strings. And I don't want to use **kwargs which defeats the purpose of the required arguments.
def func(a, b, c):
for argument, argument_value in sorted(list(locals().items())):
print(argument, ':', argument_value)
argument_value = ' '.join(argument_value.split())
print(argument, ':', argument_value)
print('a is now:', a)
func(a=' a test 1 ', b=' b test 2 ', c='c test 3')
Output
a : a test 1
a : a test 1
b : b test 2
b : b test 2
c : c test 3
c : c test 3
a is now: a test 1
Desired output for the original 'a' argument:
a is now : a test 1
Being a newb, I cobbled this together and then read the python documentation which clearly states.
locals()
Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is
called in function blocks, but not in class blocks.
Note
The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the
interpreter.
What is the right way to do what I'm attempting here?
You can use a decorator to do that kind of task.
The idea is to mask the real function behind a decorator that will take generic arguments, do modifications "on them" (actually create new variables containing the modifications) and pass the modified arguments to the real function.
def strip_blanks(f):
def decorated_func(*args, **kwargs):
# Strip blanks from non-keyword arguments
new_args = [ " ".join(arg.split()) for arg in args]
# Strip blanks from keyword arguments
new_kwargs = { key:" ".join(arg.split()) for key,arg in kwargs.items()}
# Pass the modified arguments to the decorated function
# And forward its result in case needed
return f(*new_args, **new_kwargs)
return decorated_func
#strip_blanks
def func(a, b, c):
for i in a, b, c:
print(i)
Then you'd get
>>> func(a = " foo bar", b = "baz boz", c = "biz buz ")
foo bar
baz boz
biz buz
>>> func(" foo bar", "baz boz", "biz buz ")
foo bar
baz boz
biz buz
>>> func(a = " foo bar", b = "baz boz", c = "biz buz ", d = " ha ha")
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
func(a = " foo bar", b = "baz boz", c = "biz buz ", d = " ha ha")
File "<pyshell#35>", line 5, in decorated_func
f(*new_args, **new_kwargs)
TypeError: func() got an unexpected keyword argument 'd'
>>>
I would start by changing your definition to def func(**kwargs). This takes whatever keyword arguments you provide and adds them to a dictionary. For example:
def func(**kwargs):
for key in kwargs:
print key, kwargs[key]
>>> func(a='hello', b='goodbye')
a hello
b goodbye
>>> func()
>>>
As you can see, it works with no arguments as well (nothing to print). From there, have a look at the string method strip.
EDIT:
You're giving some pretty arbitrary restrictions. So, what you want is:
...a specific number of arguments with specific names.
...to loop over the arguments.
...perform some work on each one.
The fastest way to do what you want is with locals() I think. I'm guessing what you're balking at is the bit about the contents of the dictionary not being modified. This isn't a concern here, as you're looping over a list of tuples representing the keys and values from the locals dictionary. When you do for argument, argument_value in ____ you are unpacking the tuples and assigning one value to each of those names. When you then do argument_value = 'blahblah' you are assigning a new string to argument_value. Strings are immutable, so you can't change the value "in placed". You aren't changing the value in the dictionary, as you haven't assigned anything to the dictionary's key.

Iterate over *args?

I have a script I'm working on where I need to accept multiple arguments and then iterate over them to perform actions. I started down the path of defining a function and using *args. So far I have something like below:
def userInput(ItemA, ItemB, *args):
THIS = ItemA
THAT = ItemB
MORE = *args
What I'm trying to do is get the arguments from *args into a list that I can iterate over. I've looked at other questions on StackOverflow as well as on Google but I can't seem to find an answer to what I want to do. Thanks in advance for the help.
To get your precise syntax:
def userInput(ItemA, ItemB, *args):
THIS = ItemA
THAT = ItemB
MORE = args
print THIS,THAT,MORE
userInput('this','that','more1','more2','more3')
You remove the * in front of args in the assignment to MORE. Then MORE becomes a tuple with the variable length contents of args in the signature of userInput
Output:
this that ('more1', 'more2', 'more3')
As others have stated, it is more usual to treat args as an iterable:
def userInput(ItemA, ItemB, *args):
lst=[]
lst.append(ItemA)
lst.append(ItemB)
for arg in args:
lst.append(arg)
print ' '.join(lst)
userInput('this','that','more1','more2','more3')
Output:
this that more1 more2 more3
>>> def foo(x, *args):
... print "x:", x
... for arg in args: # iterating! notice args is not proceeded by an asterisk.
... print arg
...
>>> foo(1, 2, 3, 4, 5)
x: 1
2
3
4
5
edit: See also How to use *args and **kwargs in Python (As referenced by Jeremy D and subhacom).
If you do that :
def test_with_args(farg, *args):
print "formal arg:", farg
for arg in args:
print "other args:", arg
Other information: http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
MORE = args
Or, directly:
for arg in args:
print "An argument:", arg
If your question is "how do I iterate over args", then the answer is "the same way you iterate over anything": for arg in args: print arg.
Just iterate over args:
def userInput(ItemA, ItemB, *args):
THIS = ItemA
THAT = ItemB
for arg in args:
print arg

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