Skip to main content
Missing a word in Caveats
Source Link
Miladiouss
  • 4.8k
  • 1
  • 34
  • 38
  1. ** is exclusively reserved for dictionaries.
  2. Non-optional argument assignment happens first.
  3. You cannot use a non-optional argument twice.
  4. If applicable, ** must come after *, always.
  1. ** is exclusively reserved for dictionaries.
  2. Non-optional argument assignment happens first.
  3. You cannot a non-optional argument twice.
  4. If applicable, ** must come after *, always.
  1. ** is exclusively reserved for dictionaries.
  2. Non-optional argument assignment happens first.
  3. You cannot use a non-optional argument twice.
  4. If applicable, ** must come after *, always.
The code is well commented now and there is more explanation.
Source Link
Miladiouss
  • 4.8k
  • 1
  • 34
  • 38

For those of you who learn by examples!

  1. The purpose of * is to give you the ability to define a function that can take an arbitrary number of arguments provided as a list (e.g. f(*myList) ).
  2. The purpose of ** is to give you the ability to feed a function's arguments by providing a dictionary (e.g. f(**{'x' : 1, 'y' : 2}) ).

For those of you who learnLet us show this by examples:defining a function that takes two normal variables x, y, and can accept more arguments as myArgs, and can accept even more arguments as myKW. Later, we will show how to feed y using myArgDict.

def f(normal_inputx, *argsy, **kw*myArgs, **myKW):
    #print("# Printx the length of args and kw= in{}".format(x))
 a friendly  print("# y      = {}".format(y))
    print("len(args)"# myArgs = {}".format(myArgs))
 and len  print(kw)"# myKW   = {}".format(len(argsmyKW),)
 len   print(kw))"# ----------------------------------------------------------------------")

l# =Define a list(range(5)) for demonstration purposes
dmyList    = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict    = {"k0""Wubba":"v0" "lubba", "k1""Dub":"v1" "dub"}
# Define a dictionary to feed y
f(42,myArgDict 0,= 1,{'y': 2"Why?", 3,'y0': 4"Why not?", 5)"q": "Here is a cue!"}

# len(args)The =1st 6elem andof len(kw)myList =feeds 0
y
f(42"myEx", l)*myList, **myDict)
# len(args)x      = 1myEx
# andy len(kw)     = 0Left
f# myArgs = (42'Right', d)'Up', 'Down')
# len(args)myKW   = 1{'Wubba': and'lubba', len(kw)'Dub': ='dub'}
# 0----------------------------------------------------------------------

f(42,# *l)y is matched and fed first
# len(args)The =rest 5of andmyArgDict len(kw)becomes =additional 0arguments feeding myKW
f(42"myEx", *d**myArgDict)  
# len(args)x = 2 and len(kw)  = 0

try:myEx
# y   f(42, **l)  = Why?
# GivesmyArgs an= error()
except# TypeError:
myKW   = print("l{'y0': in'Why f(**l)not?', is'q': not'Here is a dictionarycue!")'}
# ----------------------------------------------------------------------

# The rest of myArgDict becomes additional arguments feeding myArgs
f(42"myEx", **d*myArgDict)
# x      = myEx
# len(args)y      = 0y
# andmyArgs len= (kw'y0', 'q')
# myKW   = 2{}
# ----------------------------------------------------------------------

# WithoutFeed explicitlyextra feedingarguments normal_input
#manually l[0]and becomesappend normal_inputeven more from my list
f(*l"myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x      = myEx
# len(args)y      = 4
# andmyArgs len= (kw42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW   = 0{'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# Let'sWithout trythe everythingstars, nowthe entire provided list and dict become x, and y:
f(42myList, 420,myDict)
# 4200x      = ['Left', *l'Right', **d)'Up', 'Down']
# len(args)y      = 7{'Wubba': and'lubba', len'Dub': 'dub'}
# myArgs = (kw)
# myKW   = 2{}
# ----------------------------------------------------------------------

Notice the first argument is the normal_input, the 2nd, 3rd, and *l are the next 7 arguments.

Caveats

  1. ** is exclusively reserved for dictionaries.
  2. Non-optional argument assignment happens first.
  3. You cannot a non-optional argument twice.
  4. If applicable, ** must come after *, always.

For those of you who learn by examples:

def f(normal_input, *args, **kw):
    # Print the length of args and kw in a friendly format
    print("len(args) = {} and len(kw) = {}".format(len(args), len(kw)))

l = list(range(5))
d = {"k0":"v0", "k1":"v1"}

f(42, 0, 1, 2, 3, 4, 5) # len(args) = 6 and len(kw) = 0

f(42, l) # len(args) = 1 and len(kw) = 0
f(42, d) # len(args) = 1 and len(kw) = 0

f(42, *l) # len(args) = 5 and len(kw) = 0
f(42, *d) # len(args) = 2 and len(kw) = 0

try:
    f(42, **l) # Gives an error
except TypeError:
    print("l in f(**l) is not a dictionary!")

f(42, **d) # len(args) = 0 and len(kw) = 2

# Without explicitly feeding normal_input
# l[0] becomes normal_input
f(*l) # len(args) = 4 and len(kw) = 0

# Let's try everything now
f(42, 420, 4200, *l, **d) # len(args) = 7 and len(kw) = 2

Notice the first argument is the normal_input, the 2nd, 3rd, and *l are the next 7 arguments.

For those of you who learn by examples!

  1. The purpose of * is to give you the ability to define a function that can take an arbitrary number of arguments provided as a list (e.g. f(*myList) ).
  2. The purpose of ** is to give you the ability to feed a function's arguments by providing a dictionary (e.g. f(**{'x' : 1, 'y' : 2}) ).

Let us show this by defining a function that takes two normal variables x, y, and can accept more arguments as myArgs, and can accept even more arguments as myKW. Later, we will show how to feed y using myArgDict.

def f(x, y, *myArgs, **myKW):
    print("# x      = {}".format(x))
    print("# y      = {}".format(y))
    print("# myArgs = {}".format(myArgs))
    print("# myKW   = {}".format(myKW))
    print("# ----------------------------------------------------------------------")

# Define a list for demonstration purposes
myList    = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict    = {"Wubba": "lubba", "Dub": "dub"}
# Define a dictionary to feed y
myArgDict = {'y': "Why?", 'y0': "Why not?", "q": "Here is a cue!"}

# The 1st elem of myList feeds y
f("myEx", *myList, **myDict)
# x      = myEx
# y      = Left
# myArgs = ('Right', 'Up', 'Down')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# y is matched and fed first
# The rest of myArgDict becomes additional arguments feeding myKW
f("myEx", **myArgDict) 
# x      = myEx
# y      = Why?
# myArgs = ()
# myKW   = {'y0': 'Why not?', 'q': 'Here is a cue!'}
# ----------------------------------------------------------------------

# The rest of myArgDict becomes additional arguments feeding myArgs
f("myEx", *myArgDict)
# x      = myEx
# y      = y
# myArgs = ('y0', 'q')
# myKW   = {}
# ----------------------------------------------------------------------

# Feed extra arguments manually and append even more from my list
f("myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x      = myEx
# y      = 4
# myArgs = (42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# Without the stars, the entire provided list and dict become x, and y:
f(myList, myDict)
# x      = ['Left', 'Right', 'Up', 'Down']
# y      = {'Wubba': 'lubba', 'Dub': 'dub'}
# myArgs = ()
# myKW   = {}
# ----------------------------------------------------------------------

Caveats

  1. ** is exclusively reserved for dictionaries.
  2. Non-optional argument assignment happens first.
  3. You cannot a non-optional argument twice.
  4. If applicable, ** must come after *, always.
Source Link
Miladiouss
  • 4.8k
  • 1
  • 34
  • 38

For those of you who learn by examples:

def f(normal_input, *args, **kw):
    # Print the length of args and kw in a friendly format
    print("len(args) = {} and len(kw) = {}".format(len(args), len(kw)))

l = list(range(5))
d = {"k0":"v0", "k1":"v1"}

f(42, 0, 1, 2, 3, 4, 5) # len(args) = 6 and len(kw) = 0

f(42, l) # len(args) = 1 and len(kw) = 0
f(42, d) # len(args) = 1 and len(kw) = 0

f(42, *l) # len(args) = 5 and len(kw) = 0
f(42, *d) # len(args) = 2 and len(kw) = 0

try:
    f(42, **l) # Gives an error
except TypeError:
    print("l in f(**l) is not a dictionary!")

f(42, **d) # len(args) = 0 and len(kw) = 2

# Without explicitly feeding normal_input
# l[0] becomes normal_input
f(*l) # len(args) = 4 and len(kw) = 0

# Let's try everything now
f(42, 420, 4200, *l, **d) # len(args) = 7 and len(kw) = 2

Notice the first argument is the normal_input, the 2nd, 3rd, and *l are the next 7 arguments.