442

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

fn(a, b)
fn(a, b, c, d, ...)
5
  • 6
    I refer the honorable lottness to podcast 53: itc.conversationsnetwork.org/shows/… Commented May 28, 2009 at 11:10
  • 3
    I gotta go with Mr Lott on this one. You can quickly get an authorative answer on this one in the Python docs, plus you'll get a feel for what else is there in the docs. It is to your benefit to get to know those docs if you plan on working in Python. Commented May 28, 2009 at 19:41
  • @DavidSykes Link is broken Commented Jun 6, 2019 at 18:06
  • The episode #53 "let's go Rio" cannot be the one mentioned by @DavidSykes in 2009, since it was recorded in 2013. Strangely, there was another #53 also recorded in 2011, also after David's comment: open.spotify.com/episode/… Commented Mar 1, 2023 at 9:22
  • @ouranos Could it be this #53? stackoverflow.blog/podcast/page/46 Commented Mar 2, 2023 at 16:35

6 Answers 6

563

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Also important...one may find a time when they have to pass an unknown number of arguments to a function. In a case like this call your "manyArgs" by creating a list called "args" and passing that to manyArgs like this "manyArgs(*args)"
This is close, but this is unfortunately not general enough: manyArgs(x = 3) fails with TypeError. Skumedel's answer shows the solution to this. The key point is that the general signature of a function is f(*list_args, **keyword_args) (not f(*list_args)).
The type of args is tuple. kwargs means keyword args. The type of kwargs is dictionary.
Just for arg in args: for iterating through passed args
I have to pass variable number of integer parameters followed by optional string, can I call use xxx(*arg: int, log: str = "") ? The variety in the number of parameters is small 0, 1, 2 or 3, so I can use overloads but it seems like it is not not available in python.
269

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.

6 Comments

Not sure how you got myfunc(abc=123, def=456) to work, but in mine (2.7), 'def' can't be passed in this function without getting a SyntaxError. I assume this is because def has meaning in python. Try myfunc(abc=123,fgh=567) instead. (Otherwise, great answer and thanks for it!)
@Dannid: No idea either haha... doesn't work on 2.6 or 3.2 either. I'll rename it.
When you say 'called in that order', do you mean passed in that order? Or something else?
@NikhilPrabhu: Yeah. Keyword arguments must come last when you call it. They always come last if you have non-keyword arguments in the call too.
For Python 3: Just exchange print a with print(a), and kwargs.iteritems(): with kwargs.items().
|
28

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

Comments

13

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)

Comments

1
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

1 Comment

This is terrible code. Far better would be: f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')
1

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

1 Comment

Since the question implies a variable number of items this answer is not really applicable. More generally you can mix a fixed number items passed by position and a variable number of arguments pass by value. e.g. def test(a b, **kwargs).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.