DEV Community

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

Posted on • Edited on

Unpacking in Python (1)

Buy Me a Coffee

*Memo:

  • 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 the dictionary unpacking with ** and a function.
  • My post explains *args.
  • My post explains **kwargs.
  • My post explains a variable assignment.
  • My post explains a function (1).

Iterable unpacking can be done without * and with an assignment statement as shown below:

*Memo:

  • The syntax of the one or more variables and commas(,), tuples(()) and/or lists([]) with = iterable is an iterable unpacking:
    • v, = [0] and v = [0] are different.
    • One or more variables and commas are a tuple even if () isn't used.
    • Lists are converted to tuples if lists are explicitly used on the left side of =:
  • The number of variables must match the number of the elements in an iterable unless a *variable is used on the left side of =:
    • Only one *variable can be used within each tuple and list on the left side of = to flexibly accept the zero or more elements of an iterable:
      • A *variable is the list whose default value is [] so the type is list.
      • A *variable cannot be used outside any list and tuple.
    • A **variable cannot be used.
  • One or more *iterables can be used within each list, tuple and set literal on the right side of = to unpack iterables:
    • A *iterable cannot be used outside any list, tuple and set literal.
    • 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.
  • One or more **dictionaries can be used within each dictionary(dict) literal on the right side of = to unpack dictionaries:
    • A **dictionary cannot be used outside any dictionary(dict) literal.
    • ** cannot be used with an iterable except a dictionary.
  • 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 on the right side of = and used as the arguments within a function call including print() to unpack iterables are iterable unpacking operators but the only one *variable used within each tuple and list on the left side of = to flexibly accept the zero or more elements of an iterable isn't an iterable unpacking operator:
    • The iterable unpacking operator * can unpack(flat) only the most outer dimension of an iterable.
  • 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 on the right side of = 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.
  • The doc explains an assignment statement.
v1, v2, v3 = [0, 1, 2]                # list
v1, v2, v3 = (0, 1, 2)                # tuple
v1, v2, v3 = {0, 1, 2}                # set
v1, v2, v3 = frozenset({0, 1, 2})     # frozenset
v1, v2, v3 = iter([0, 1, 2])          # iterator
v1, v2, v3 = '012'                    # str
v1, v2, v3 = range(3)                 # range

print(v1, v2, v3)
# 0 1 2

v1, v2, v3 = {0:1, 2:3, 4:5}          # dict
v1, v2, v3 = {0:1, 2:3, 4:5}.keys()   # dict.keys()

print(v1, v2, v3)
# 0 2 4

v1, v2, v3 = {0:1, 2:3, 4:5}.values() # dict.values()

print(v1, v2, v3)
# 1 3 5

v1, v2, v3 = {0:1, 2:3, 4:5}.items()  # dict.items()

print(v1, v2, v3)
# (0, 1) (2, 3) (4, 5)

v1, = '0'                             # str
v2, = v1
v3, = v2

print(v1, v2, v3)
# 0 0 0

v1, v2, v3 = b'012'                   # bytes
v1, v2, v3 = bytearray(b'012')        # bytearray

print(v1, v2, v3)
# 48 49 50

v1, v2, v3 = [0, 1, 2]
(v1, v2, v3) = [0, 1, 2]
[v1, v2, v3] = [0, 1, 2]

print(v1, v2, v3)
# 0 1 2

v1, v2 = [0, [1, [2]]]
(v1, v2) = [0, [1, [2]]]
[v1, v2] = [0, [1, [2]]]

print(v1, v2)
# 0 [1, [2]]

v1, (v2, v3) = [0, [1, [2]]]
v1, [v2, v3] = [0, [1, [2]]]
(v1, (v2, v3)) = [0, [1, [2]]]
[v1, [v2, v3]] = [0, [1, [2]]]

print(v1, v2, v3)
# 0 1 [2]

v1, (v2, (v3,)) = [0, [1, [2]]]
v1, [v2, [v3]] = [0, [1, [2]]]
(v1, (v2, (v3,))) = [0, [1, [2]]]
[v1, [v2, [v3]]] = [0, [1, [2]]]

print(v1, v2, v3)
# 0 1 2

v, = [0]
(v,) = [0]
[v] = [0]

print(v)
# 0

# It's not an iterable unpacking.
v = [0, 1, 2] 

print(v)
# [0, 1, 2]

# It's not an iterable unpacking.
v = [0]

print(v)
# [0]

# It's not an iterable unpacking.
v1 = v2 = v3 = [0, 1, 2]

print(v1, v2, v3)
# [0, 1, 2] [0, 1, 2] [0, 1, 2]

v1, v2, v3 = [0, 1]
# ValueError: not enough values to unpack (expected 3, got 2)

v1, v2, v3 = [0, 1, 2, 3]
# ValueError: too many values to unpack (expected 3)

v, = []
# ValueError: not enough values to unpack (expected 1, got 0)

v, = 0
# TypeError: cannot unpack non-iterable int object
Enter fullscreen mode Exit fullscreen mode

Top comments (0)