*args vs list in codecademy's example

Hey there !

I’ve found the last example there (https://www.codecademy.com/courses/learn-intermediate-python-3/lessons/function-arguments-args-kwargs/exercises/function-call-unpacking) absolutely confusing.

Here’s the code

num_collection = [3, 6, 9]
 
def power_two(*nums): 
  for num in nums:
    print(num**2)
 
power_two(*num_collection)

Which will print

9
36
81

Now the question is… Why bother use * in this case? This seems to do exactly the same as the following

num_collection = [3, 6, 9]
 
def power_two(nums): 
  for num in nums:
    print(num**2)
 
power_two(num_collection)

Which will print exactly the same

9
36
81

Can someone please explain to me what I’m missing? Is it really better to use * in this very example?
I understand why (and I think when) to use them, but I don’t understand in this example why it would be better than using a single list argument. They both seem to offer same flexibility in this case.

Thank you for your time,

Antoine

1 Like

putting *arg in a function allows for an arbitrary number of arguments to be put in the function, ie, you can replace “num” with one item, two items, or two hundred items. While in this case, you are importing a single list and iterating through it, putting *args in your function is a future-proof way of ensuring that your code will still function as expected when the inputs change.

This article gives more explanation on function arguments and keyword arguments, for further reading.

Hey thank you for your answer,

I understand why and when to use them, I just thought that this very example Codecademy shows here is actually less convenient than simply using a list. Unless I didn’t think of a specific case.
They are themselves passing a list as argument here…

*args is an unbounded sequence, meaning an indefinite number of positional arguments. A list is a single positional argument. We don’t need to use splat if we are writing our function to take a list.

1 Like

It’s probably better to show it this way:

num_collection = [3, 6, 9]

num2_collection = [2, 4, 6]

def power_two(*nums): 
  for num in nums:
    print(num**2)
 
power_two(*num_collection, *num2_collection)

Having the star in the function definition allows any number of arguments.
Having the star in the function call unpacks the list and feeds it into the function call.

power_two(*num_collection) is the same as power_two(3, 6, 9)
power_two(num_collection) is the same as power_two([3,6,9])

the first has 3 arguments, the second has one.

1 Like

Yes yes like that, I would have agreed ! But Codecademy should have come up with your example !
Unpacking multiple lists without knowing how many before the call.
Not simply passing one list as I show above. There is no point in using * if you know you’ll pass only one list.

Anyway, thank you all for replies :slight_smile:

The very last sentence is why I posted, since their example passes only one list.
I was wondering if it has another benefit than being able to pass multiple lists.
In other words, if it has more benefit when passing one list only, compared to the second code I posted, that doesn’t uses *.

But you replied to that in your last sentence, Thanks !

1 Like