DEV Community

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

Posted on • Edited on

Unpacking in Python (6)

Buy Me a Coffee

*Memo:

  • 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 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 dictionary unpacking with ** and a function.
  • My post explains *args.
  • My post explains **kwargs.

Iterable unpacking can be done with * and print() as shown below:

*Memo:

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

<Iterable unpacking within print()>:

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,                       # frozenset
      *frozenset({3, 4, *frozenset({5})}))
print(*iter([0, 1]), 2, *iter([3, 4, *iter([5])])) # iterator
print(*'0123', *'45')                              # str
print(*range(4), *range(4, 6))                     # range
# 0 1 2 3 4 5

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

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

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

print(*b'0123', *b'45')                            # bytes
print(*bytearray(b'0123'), *bytearray(b'45'))      # bytearray
# 48 49 50 51 52 53

print(*[0, 1], 2, *[3, 4, *[5]], # list
      *b'0123', *b'45',          # bytes
      *{0, 1}, 2, *{3, 4, *{5}}) # set
# 0 1 2 3 4 5 48 49 50 51 52 53 0 1 2 3 4 5
Enter fullscreen mode Exit fullscreen mode

<Iterable unpacking within a list literal>:

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,                        # frozenset
       *frozenset({3, 4, *frozenset({5})})])
print([*iter([0, 1]), 2, *iter([3, 4, *iter([5])])]) # iterator
print([*range(4), *range(4, 6)])                     # range
# [0, 1, 2, 3, 4, 5]

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

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

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

print([*'0123', *'45'])                              # str
# ['0', '1', '2', '3', '4', '5']

print([*b'0123', *b'45'])                            # bytes
print([*bytearray(b'0123'), *bytearray(b'45')])      # bytearray
# [48, 49, 50, 51, 52, 53]

print([*[0, 1], 2, *[3, 4, *[5]],  # list
       *b'0123', *b'45',           # bytes
       *{0, 1}, 2, *{3, 4, *{5}}]) # set
# [0, 1, 2, 3, 4, 5, 48, 49, 50, 51, 52, 53, 0, 1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

<Iterable unpacking within a tuple literal>:

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,                        # frozenset
       *frozenset({3, 4, *frozenset({5})})))
print((*iter([0, 1]), 2, *iter([3, 4, *iter([5])]))) # iterator
print((*range(4), *range(4, 6)))                     # range
# (0, 1, 2, 3, 4, 5)

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

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

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

print((*'0123', *'45'))                              # str
# ('0', '1', '2', '3', '4', '5')

print((*b'0123', *b'45'))                            # bytes
print((*bytearray(b'0123'), *bytearray(b'45')))      # bytearray
# (48, 49, 50, 51, 52, 53)

print((*[0, 1], 2, *[3, 4, *[5]],  # list 
       *b'0123', *b'45',           # bytes
       *{0, 1}, 2, *{3, 4, *{5}})) # set
# (0, 1, 2, 3, 4, 5, 48, 49, 50, 51, 52, 53, 0, 1, 2, 3, 4, 5)
Enter fullscreen mode Exit fullscreen mode

<Iterable unpacking within a set literal>:

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,                        # frozenset
       *frozenset({3, 4, *frozenset({5})})})
print({*iter([0, 1]), 2, *iter([3, 4, *iter([5])])}) # iterator
print({*range(4), *range(4, 6)})                     # range
# {0, 1, 2, 3, 4, 5}

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

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

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

print({*'0123', *'45'})                              # str
# {'5', '3', '0', '4', '1', '2'}

print({*b'0123', *b'45'})                            # bytes
print({*bytearray(b'0123'), *bytearray(b'45')})      # bytearray
# {48, 49, 50, 51, 52, 53}

print({*[0, 1], 2, *[3, 4, *[5]],  # list
       *b'0123', *b'45',           # bytes   
       *{0, 1}, 2, *{3, 4, *{5}}}) # set
# {0, 1, 2, 3, 4, 5, 48, 49, 50, 51, 52, 53}
Enter fullscreen mode Exit fullscreen mode

<Iterable unpacking within a dictionary(dict) literal>:

print({'A':'B', *[0, 1, 2], 'C':'D'})            # list
print({'A':'B', *(0, 1, 2), 'C':'D'})            # tuple
print({'A':'B', *{0, 1, 2}, 'C':'D'})            # set
print({'A':'B', *frozenset({0, 1, 2}), 'C':'D'}) # frozenset
print({'A':'B', *{0:1, 2:3}, 'D':'E'})           # dict
print({'A':'B', *{0:1, 2:3}.keys(), 'C':'D'})    # dict.keys()
print({'A':'B', *{0:1, 2:3}.values(), 'C':'D'})  # dict.values()
print({'A':'B', *{0:1, 2:3}.items(), 'C':'D'})   # dict.items()
print({'A':'B', *iter([0, 1, 2]), 'C':'D'})      # iterator
print({'A':'B', *'012', 'C':'D'})                # str
print({'A':'B', *b'012', 'C':'D'})               # bytes
print({'A':'B', *bytearray(b'012'), 'C':'D'})    # bytearray
print({'A':'B', *range(3), 'C':'D'})             # range
# SyntaxError: invalid syntax
Enter fullscreen mode Exit fullscreen mode

Top comments (0)