I am fairly new to Python3. I have a question with Variable Length Arguments(*args). Based on my understanding the reason why we use the Variable Length Arguments list(or tuple) is that they are useful when you need a function that may have different numbers of arguments. A function like this
def main(): x = ('meow', 'grrr', 'purr') kitten(*x) def kitten(*args): if len(args): for s in args: print(s) else: print('Empty') if __name__ == '__main__': main()
gives the same output as
def main(): x = ('meow', 'grrr', 'purr') kitten(x) def kitten(args): if len(args): for s in args: print(s) else: print('Empty') if __name__ == '__main__': main()
output
meow grrr purr
I don’t see the difference, and why is it better to use Variable Length Arguments(*args). Could someone please explain this to me?
And also, what does the asterisk really do?
x = ('meow', 'grrr', 'purr') print (*x)
output
meow grrr purr
seems like, it just takes the variables inside the tuple out. And if I do
print (len(*x)) print (type(*x))
it will give me error
print (len(*x)) TypeError: len() takes exactly one argument (3 given)
print(type(*x)) TypeError: type.__new__() argument 2 must be tuple, not str
Advertisement
Answer
When *
is used before a iterable
like list
or tuple
, it expands (unpack) the content of the iterable
.
So, when you have:
x = ('meow', 'grrr', 'purr') print(*x)
your output is:
meow grrr purr
Here, x
is a tuple
, which is iterable
, so *
expanded the content of x
before printing them.
BUT
When, *
is used infront of the parameter
in a function
or method
, it allows us to pass variable number of
arguments.
In your example,
def main(): x = ('meow', 'grrr', 'purr') kitten(*x) def kitten(*args):
you are expanding the values stored in x
in line kitten(*x)
before passing it to the function kitten
.
And your function kitten(*args)
is defined to accept variable number of arguments. Because of *args
, you were able to pass
3 arguments to it, meow
grrr
purr
.
In second example:
def main(): x = ('meow', 'grrr', 'purr') kitten(x) def kitten(args):
You are passing only one argument to the function kitten()
, which is x
, and its type is tuple
.
Advantage of using *args
If you choose to use list
or tuple
as in your example.
First, you need to create a list
or tuple
before calling the function
.
Second, if you use list
, you have to be cautious of the fact
the list
is mutable, so if the list
is modified inside the function, changes can be seen outside of the function as well.
Example
def main(): x = [1, 2, 3] >>> print(x) >>> [1, 2, 3] f(x) >>> print(x) >>> [9, 2, 3] def f(x): x[0] = 9 main()
But, if you use *args
, you don’t have to worry about any of this stuff.
In your case, you have used tuple
, which is immutable
so, you don’t have to worry about the mutable
issue.