-1

This question is to try to understand what the asterisk(*) works. As known, * could be used with args to make the function accept positional keywords later. Also, it could work as an operator to unpack a container. So my question is:

how to know its functionality?

def product(*num):
    prod = 1
    for i in num:
        prod*= i
    return prod

def product2(num):
    prod = 1
    for i in num:
        prod*= i
    return prod

num = [2,3,5]

So when you use different function, you will get different result. I just wanted to know what happened here? Thanks.

Simon
  • 5,464
  • 6
  • 49
  • 85
Ted
  • 1
  • without * it accept only one object (of course you can use one list or one dictionary to send many values). – furas Jul 06 '19 at 22:27
  • With `def product(*num):`, you are expected to pass the numbers to be multiplied as individual arguments, rather than in a list. The `*num` will pack them up for the function. You should call `product(2, 3, 5)` to get the same result as `product2(num)`. You can also use an `*` in the call, to unpack your `num` list as separate arguments (that will be repacked in the function): `product(*num)`. – Blckknght Jul 06 '19 at 22:30

2 Answers2

2

When doing product(num), you get the arguments as a list. Hence, step by step:

def product(*num):
    # num = [[2, 3, 5]]
    prod = 1
    for i in num:
        # i = [2, 3, 5]
        prod*= i    # prod = 1 * [2, 3, 5]
        # prod = [2, 3, 5]
    return prod

The second function, product2(num), works as expected, calculating 1 * 2 * 3 * 5 = 30.

Simon
  • 5,464
  • 6
  • 49
  • 85
  • In [How to Answer](https://stackoverflow.com/help/how-to-answer), note the section "Answer Well-Asked Questions", and therein the bullet point regarding questions "that have been asked and answered many times before". – Charles Duffy Jul 06 '19 at 22:35
0

*num means that all further positional arguments will be put into num:

def test(*nums):
    print(nums)

test(1)            # (1,)
test(1, 2, 3, 4)   # (1, 2, 3, 4)

num* means that all values in num will be unpacked into positional arguments.

def test(*nums):
    print(nums)

test([1]*)            # (1,)
test([1, 2, 3, 4]*)   # (1, 2, 3, 4)

In your case product will multiply all of its positional arguments while product2 expects a single argument containing some sort of list with the numbers.

def product(*num):  # num = ([2, 3, 5],)
    prod = 1
    for i in num:   # i = [2, 3, 5]
        prod*= i    # prod = 1 * [2, 3, 5]
    return prod     # [2, 3, 5]

def product2(num):  # num = [2, 3, 5]
    prod = 1
    for i in num:   # i = 2; i = 3; i = 5
        prod*= i    # prod = 1 * 2; prod = 2 * 3; prod = 6 * 5
    return prod     # 30

num = [2, 3, 5]

If you want the first one to work you can just unpack the arguments:

product(num*)  # equivalent to product(2, 3, 5)
Alex
  • 963
  • 9
  • 11
  • In [How to Answer](https://stackoverflow.com/help/how-to-answer), note the section "Answer Well-Asked Questions", and therein the bullet point regarding questions "that have been asked and answered many times before". – Charles Duffy Jul 06 '19 at 22:35