DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on • Edited on

Unpacking in Python (9)

Buy Me a Coffee

*Memo:

  • My post explains the unpacking with an assignment statement (1).
  • My post explains the unpacking with an assignment statement (2).
  • My post explains the unpacking with a for statement (1).
  • My post explains the unpacking with a for statement (2).
  • My post explains the unpacking with a for statement (3).
  • My post explains the iterable unpacking with * and a function (1).
  • My post explains the iterable unpacking with * and a function (2).
  • My post explains the iterable unpacking with * and a function (3).
  • My post explains *args.
  • My post explains **kwargs.

Dictionary unpacking can be done with ** within a dictionary and with a function as shown below:

*Memo:

  • One or more **dictionaries can be used within each dictionary(dict) literal to unpack dictionaries:
    • A **dictionary cannot be used outside any dictionary(dict) literal on the right side of parameter= to unpack a dictionary.
  • One or more **dictionaries can be used as the arguments within a function call excluding print() to unpack them into the one or more parameters including **kwargs but excluding *args within a function definition:
    • One or more **dictionaries can be used with **kwargs but not with *args and within print().
  • The only one parameter with ** which is **kwargs conventionally can be used within a function definition:
    • A **kwargs is the dictionary parameter which can flexibly accept zero or more keyward arguments so the type is dict.
    • A **kwargs is called a var-keyword parameter.
    • A **kwargs is the optional parameter with the immutable default value {} so the default value {} cannot be changed with =.
    • A **kwargs must be the last parameter.
    • A **kwargs can be other names like **teachers, **students, etc.
  • A ** is called a dictionary unpacking operator to unpack a dictionary as the name suggests so the one or more **dictionaries used within each dictionary(dict) literal and used as the arguments within a function call excluding print() to unpack dictionaries are dictionary unpacking operators:
    • The dictionary unpacking operator ** can unpack(flat) only the most outer dimension of a dictionary.
  • A string(str) can be unpacked infinitely because even the single character unpacked is also the string(str) which is an iterable.

<Dictionary unpacking with print()>:

# dict
print({**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}})
print({**{0:1, 2:3}, 4:5, **{6:7, 8:9, **{10:11}}})
# {0: 1, 2: 3, 4: 5, 6: 7, 8: 9, 10: 11}

# dict.keys()
print({**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.keys()})
# TypeError: 'dict_keys' object is not a mapping

# dict.values()
print({**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.values()})
# TypeError: 'dict_values' object is not a mapping

# dict.items()
print({**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.items()})
# TypeError: 'dict_items' object is not a mapping

print(**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11})
# TypeError: keywords must be strings

print(**{'A':'B', 'C':'D', 'E':'F', 'G':'H', 'I':'J', 'K':'L'})
# TypeError: 'A' is an invalid keyword argument for print()
Enter fullscreen mode Exit fullscreen mode

<print(**iterable)>:

print(**[0, 1, 2, 3, 4, 5])                        # list
print(**(0, 1, 2, 3, 4, 5))                        # tuple
print(**{0, 1, 2, 3, 4, 5})                        # set
print(**frozenset({0, 1, 2, 3, 4, 5}))             # frozenset
print(**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.keys())   # dict.keys()
print(**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.values()) # dict.values()
print(**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.items())  # dict.items()
print(**iter([0, 1, 2, 3, 4, 5]))                  # iterator
print(**'012345')                                  # str
print(**b'012345')                                 # bytes
print(**bytearray(b'012345'))                      # bytearray
print(**range(6))                                  # range
# TypeError: print() argument after ** must be a mapping, not ...
Enter fullscreen mode Exit fullscreen mode

<Dictionary unpacking with func(p=dictionary)>:

def func(p={**{0:1, 2:3}, 4:5,
            **{6:7, 8:9, **{10:11}}}):
    print(p)

func()
# {0: 1, 2: 3, 4: 5, 6: 7, 8: 9, 10: 11}
Enter fullscreen mode Exit fullscreen mode

<func(p=**iterable)>:

def func(p=**[0, 1, 2, 3, 4, 5]): pass                        # list
def func(p=**(0, 1, 2, 3, 4, 5)): pass                        # tuple
def func(p=**{0, 1, 2, 3, 4, 5}): pass                        # set
def func(p=**frozenset({0, 1, 2, 3, 4, 5})): pass             # frozenset
def func(p=**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}): pass          # dict
def func(p=**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.keys()): pass   # dict.keys()
def func(p=**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.values()): pass # dict.values()
def func(p=**{0:1, 2:3, 4:5, 6:7, 8:9, 10:11}.items()): pass  # dict.items()
def func(p=**iter([0, 1, 2, 3, 4, 5])): pass                  # iterator
def func(p=**'012345'): pass                                  # str
def func(p=**b'012345'): pass                                 # bytes
def func(p=**bytearray(b'012345')): pass                      # bytearray
def func(p=**range(6)): pass                                  # range
# SyntaxError: invalid syntax
Enter fullscreen mode Exit fullscreen mode

<Dictionary unpacking with func(A, C)>:

def func(A='b', C='d'):
    print(A, C)

func()
# b d

func(**{'A':'B', 'C':'D'})
func(**{'A':'B'}, **{'C':'D'})
func(A='B', **{'C':'D'})
func(**{'A':'B'}, C='D')
func(A='B', C='D')
# B D
Enter fullscreen mode Exit fullscreen mode

<Dictionary unpacking with func(**kwargs)>:

def func(**kwargs):
    print(kwargs)
    print({0:1, **kwargs, 2:3})

func()
# {}
# {0: 1, 2: 3}

func(**{'A':'B', 'C':'D'})
func(**{'A':'B'}, **{'C':'D'})
func(A='B', **{'C':'D'})
func(**{'A':'B'}, C='D')
func(A='B', C='D')
# {'A': 'B', 'C': 'D'}
# {0: 1, 'A': 'B', 'C': 'D', 2: 3}
Enter fullscreen mode Exit fullscreen mode

<Dictionary unpacking with func(A, **kwargs)>:

def func(A='b', **kwargs):
    print(A, kwargs)
    print(A, {0:1, **kwargs, 2:3})

func()
# b {}
# b {0: 1, 2: 3}

func(**{'A':'B', 'C':'D'})
func(**{'A':'B'}, **{'C':'D'})
func(A='B', **{'C':'D'})
func(**{'A':'B'}, C='D')
func(A='B', C='D')
# B {'C': 'D'}
# B {0: 1, 'C': 'D', 2: 3}
Enter fullscreen mode Exit fullscreen mode

<Dictionary unpacking with func(*args)>:

def func(*args):
    print(args)
    print(*args)

func()
# ()
# Nothing

func(**{'A':'B', 'C':'D'})
func(**{'A':'B'}, **{'C':'D'})
func(A='B', **{'C':'D'})
func(**{'A':'B'}, C='D')
func(A='B', C='D')
# TypeError: func() got an unexpected keyword argument 'A'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)