2

I am learning arbitrary value parameter and reading stackoverflow this and this answers and other tutorials I already understood what *args and **kwargs do in python but I am facing some errors. I have two doubts, first one is:

If I run this code print(w) then I am getting this output:

def hi(*w):
    print(w)

kl = 1, 2, 3, 4
hi(kl)

output:

((1, 2, 3, 4),)

but if I run this code with print(*w) then I am getting this output:

code:

def hi(*w):
    print(*w)

kl = 1, 2, 3, 4
hi(kl)

output:

(1, 2, 3, 4)

My second doubt is:

je = {"a": 2, "b": 4, "c": 6, 4: 5}
for j in je:
    print(*je)

output

b a 4 c
b a 4 c
b a 4 c
b a 4 c

What exactly is *je doing there? How is it working in iteration?

Community
  • 1
  • 1
  • 1
    You should read about packing unpacking of arguments http://hangar.runway7.net/python/packing-unpacking-arguments – saurabh baid Oct 27 '16 at 15:33

2 Answers2

4

When you use * in declaration of the arguments def hi(*w):, it means that all the arguments will be compressed to the tuple, e.g.:

hi(kl, kl) # ((1, 2, 3, 4), (1, 2, 3, 4))

After when you use print(*w) * run unpack of your tuple.

je={"a":2,"b":4,"c":6,4:5}
for j in je:
    print(*je)

In every iteration you use unpack of your dict (you use je and get the keys of your dict like [j for j in je])

https://docs.python.org/2/tutorial/controlflow.html#tut-unpacking-arguments

Oleksandr Dashkov
  • 2,249
  • 1
  • 15
  • 29
  • i thought in every iteration its multiplying the iteration value with len of dict values ?? –  Oct 27 '16 at 15:43
  • you use 'for j in je:' so you iterate 4 times(it's a len of your dict). In your loop, on every iteration you make unpack of the keys (so you make 4 times the same operation) – Oleksandr Dashkov Oct 27 '16 at 15:50
2

Your first case, it's because you're passing kl into the function as a tuple, not as arbitrary values. Hence, *w will expand into a single element tuple with kl as the first value.

You're essentially calling:

hi((1, 2, 3, 4))

However, what I suspect you want is

hi(1, 2, 3, 4)
# or in your case
hi(*kl)

When printing in python 3, print is a function, so again. When w is a tuple and you call it like:

print(w)
# you'll get the tuple printed:
# (1, 2, 3, 4)

However, again, you can call it with arguments like:

print(1, 2, 3, 4)
# or in your case
print(*w)
# 1 2 3 4

For your second part, look at it converted to a list first:

list({"a":2,"b":4,"c":6,4:5})
# ["b", "a", 4, "c"]
# Note, dictionaries are unordered and so the list could be in any order.

If you were to then pass that to print using the * expansion:

print("b", "a", 4, c)
# or in your case
print(*["b", "a", 4, "c"])

Just note, that the * does the default iteration for you. If you wanted some other values, use je.values() or je.items()

SCB
  • 5,821
  • 1
  • 34
  • 43