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

The Question :

366 people think this question is useful

In a similar way to using varargs in C or C++:

fn(a, b)
fn(a, b, c, d, ...)

The Question Comments :

The Answer 1

473 people think this answer is useful

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.

The Answer 2

235 people think this answer is useful

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.

The Answer 3

23 people think this answer is useful

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

The Answer 4

12 people think this answer is useful

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)

The Answer 5

2 people think this answer is useful
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

The Answer 6

1 people think this answer is useful

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

Tags:

Add a Comment