2. Unpacking sequences

2.1. Unpacking values

a, b, c = 1, 2, 3
a, b, c = (1, 2, 3)
a, b, c = [1, 2, 3]
a, b, c = {1, 2, 3}

Note

Note, that set is unordered collection!

2.1.1. Too many values to unpack

a, b, c = [1, 2, 3, 4]
# ValueError: too many values to unpack (expected 3)

2.1.2. Not enough values to unpack

a, b, c, d = [1, 2, 3]
# ValueError: not enough values to unpack (expected 4, got 3)

2.2. Unpacking arbitrary number of arguments

2.2.1. Unpacking values at the right side

a, b, *others = [1, 2, 3, 4]

a           # 1
b           # 2
others      # [3, 4]

2.2.2. Unpacking values at the left side

*others, a, b = [1, 2, 3, 4]

others      # [1, 2]
a           # 3
b           # 4

2.2.3. Unpacking values at the left side

first, *middle, last = [1, 2, 3, 4]

first       # 1
middle      # [2, 3]
last        # 4

2.2.4. Cannot unpack from both sides at once

*a, b, *c = [1, 2, 3, 4]
# SyntaxError: two starred expressions in assignment

2.3. Unpacking values from function

2.3.1. Recap of assignment information

line = '4.9,3.1,1.5,0.1,setosa'

line.split(',')
# ['4.9', '3.1', '1.5', '0.1', 'setosa']
line = '4.9,3.1,1.5,0.1,setosa'

sepal_length, sepal_width, petal_length, petal_width, species = line.split(',')

sepal_length    # '4.9'
sepal_width     # '3.1'
petal_length    # '1.5'
petal_width     # '0.1'
species         # 'setosa'

2.3.2. Unpacking values at the right side

line = '4.9,3.1,1.5,0.1,setosa'

sepal_length, sepal_width, *others = line.split(',')

sepal_length    # '4.9'
sepal_width     # '3.1'
others          # ['1.5', '0.1', 'setosa']

2.3.3. Unpacking values at the left side

line = '4.9,3.1,1.5,0.1,setosa'

*features, species = line.split(',')

features        # ['4.9', '3.1', '1.5', '0.1']
species         # 'setosa'

2.3.4. Cannot unpack from both sides at once

line = '4.9,3.1,1.5,0.1,setosa'

*a, b, *c = line.split(',')
# SyntaxError: two starred expressions in assignment

2.3.5. Naming convention

  • if you’re not using features later in your code
line = '4.9,3.1,1.5,0.1,setosa'

*_, species = line.split(',')

2.4. Example

def get_iris():
    """
    Would be nice, if you can get ``dict``...
    but most programmers will return ``tuple``
    because it's a bit faster

    return {
        'sepal_length': 4.9,
        'sepal_width': 3.1,
        'petal_length': 1.5,
        'petal_width': 0.1,
        'species': 'setosa'
    }
    """
    return 4.9, 3.1, 1.5, 0.1, 'setosa'

*features, species = get_iris()

2.5. More advanced topics

Note

The topic will be continued in Intermediate and Advanced part of the book

2.6. Assignments

2.6.1. Iris dataset

  • Filename: unpacking_iris.py
  • Lines of code to write: 30 lines
  • Estimated time of completion: 20 min
  1. Mając dane z listingu poniżej

    DATA = (
        5.8, 2.7, 5.1, 1.9, 'virginica',
        5.1, 3.5, 1.4, 0.2, 'setosa',
        5.7, 2.8, 4.1, 1.3, 'versicolor',
        6.3, 2.9, 5.6, 1.8, 'virginica',
        6.4, 3.2, 4.5, 1.5, 'versicolor',
        4.7, 3.2, 1.3, 0.2, 'setosa',
    )
    
  2. Za pomocą slice wyodrębnij zmienną features: List[Tuple[float]] z wynikami pomiarów

    features = [
        (5.8, 2.7, 5.1, 1.9),
        (5.1, 3.5, 1.4, 0.2),
        (5.7, 2.8, 4.1, 1.3),
        (6.3, 2.9, 5.6, 1.8),
        (6.4, 3.2, 4.5, 1.5),
        (4.7, 3.2, 1.3, 0.2),
    ]
    
  3. Za pomocą slice (co piąty element) wyodrębnij zmienną labels: List[str], która będzie zawierała w kolejności wszystkie nazwy gatunków:

    labels = [
        'virginica',
        'setosa',
        'versicolor',
        'virginica',
        'versicolor',
        'setosa',
    ]
    
  4. Za pomocą slice wyodrębnij zmienną species: Set[str], która jest unikalnym zbiorem gatunków (na podstawie labels)

    species = {
        'versicolor',
        'setosa',
        'virginica',
    }
    
  5. Nie używaj slice, ani żadnych instrukcji, które nie zostały dotychczas omówione

The whys and wherefores:
 
  • Definiowanie i korzystanie z list, tuple, set
  • Slice zbiorów danych
  • Rzutowanie i konwersja typów

2.6.2. Hosts

  • Filename: kwargs_hosts.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 15 min
  • Input data: Code Listing 2.1.
  1. Skopiuj zawartość listingu poniżej do pliku hosts.txt
  2. Stwórz pusty dict o nazwie hosts
  3. Czytając plik pomiń puste linie lub zaczynające się od komentarza #
  4. Do hosts dla klucza IP dodaj listę hostname
  5. Przy parsowaniu linii skorzystaj z konstrukcji z gwiazdką *
Code Listing 2.1. Listing pliku /etc/hosts
##
# ``/etc/hosts`` structure:
#   - IPv4 or IPv6
#   - Hostnames
##

127.0.0.1       localhost
127.0.0.1       astromatt
10.13.37.1      nasa.gov esa.int roscosmos.ru
255.255.255.255 broadcasthost
::1             localhost