8.1. Unpack GetItem

  • Allows to get element from ordered sequence

  • Works with ordered sequences: str, list, tuple

8.1.1. Syntax

  • Index must int (positive, negative or zero)

  • Positive Index starts with 0

  • Negative index starts with -1

>>> data = ['a', 'b', 'c']
>>>
>>> data[0]
'a'
>>> data[1]
'b'
>>> data[-1]
'c'

8.1.2. Positive Index

  • Starts with 0

  • Index must be less than length of an object

  • Ascending

>>> data = ['a', 'b', 'c']
>>>
>>> data[0]
'a'
>>> data[1]
'b'
>>> data[2]
'c'
>>>
>>> data[3]
Traceback (most recent call last):
IndexError: list index out of range

8.1.3. Negative Index

  • 0 is equal to -0

  • Starts with -1

  • Descending

  • Negative index starts from the end and go right to left

>>> data = ['a', 'b', 'c']
>>>
>>> data[-0]
'a'
>>> data[-1]
'c'
>>> data[-2]
'b'
>>> data[-3]
'a'
>>>
>>> data[-4]
Traceback (most recent call last):
IndexError: list index out of range
>>> -0 == 0
True

8.1.4. Index Type

Index must int (positive, negative or zero)

>>> data[1.1]
Traceback (most recent call last):
TypeError: list indices must be integers or slices, not float

8.1.5. Getitem from str

Get Item from str:

>>> data = 'abc'
>>>
>>> data[0]
'a'
>>> data[1]
'b'
>>> data[2]
'c'
>>> data[-0]
'a'
>>> data[-1]
'c'
>>> data[-2]
'b'

8.1.6. Getitem from list

GetItem from list:

>>> data = ['a', 'b', 'c']
>>>
>>> data[0]
'a'
>>> data[1]
'b'
>>> data[2]
'c'
>>> data[-0]
'a'
>>> data[-1]
'c'
>>> data[-2]
'b'

8.1.7. Getitem from tuple

>>> data = ('a', 'b', 'c')
>>>
>>> data[0]
'a'
>>> data[1]
'b'
>>> data[2]
'c'
>>> data[-0]
'a'
>>> data[-1]
'c'
>>> data[-2]
'b'

8.1.8. Getitem from set

GetItem from set is impossible. set is unordered data structure:

>>> data = {'a', 'b', 'c', 'd'}
>>>
>>> data[0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>> data[1]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>> data[2]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>> data[-0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>> data[-1]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable
>>> data[-2]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable

8.1.9. Getitem from dict

  • GetItem with index on dict is not possible

Getting keys other than str:

>>> calendarium = {
...    1961: 'First Human Space Flight',
...    1969: 'First Step on the Moon',
... }
>>>
>>>
>>> calendarium[1961]
'First Human Space Flight'
>>>
>>> calendarium['1961']
Traceback (most recent call last):
KeyError: '1961'
>>> crew = {
...     'commander': 'Melissa Lewis',
...     'botanist': 'Mark Watney',
...     'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> crew[1]
Traceback (most recent call last):
KeyError: 1
>>>
>>> crew[0]
Traceback (most recent call last):
KeyError: 0
>>>
>>> crew[-1]
Traceback (most recent call last):
KeyError: -1

GetItem on Numeric Dict Keys:

>>> crew = {
...    0: 'Melissa Lewis',
...    1: 'Mark Watney',
...    2: 'Rick Martinez',
... }
>>>
>>>
>>> crew[0]
'Melissa Lewis'
>>>
>>> crew[1]
'Mark Watney'
>>>
>>> crew[2]
'Rick Martinez'
>>>
>>> crew[-0]
'Melissa Lewis'
>>>
>>> crew[-1]
Traceback (most recent call last):
KeyError: -1
>>>
>>> crew[-2]
Traceback (most recent call last):
KeyError: -2

8.1.10. Getitem from list[list]

Get elements from list of list:

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
...
>>> data[0][0]
1
>>> data[0][1]
2
>>> data[0][2]
3
>>> data[1][0]
4
>>> data[1][1]
5
>>> data[1][2]
6
>>> data[2][0]
7
>>> data[2][1]
8
>>> data[2][2]
9

8.1.11. Getitem from list[tuple]

Get elements from list of tuple:

>>> data = [
...     (4.7, 3.2, 1.3, 0.2, 'setosa'),
...     (7.0, 3.2, 4.7, 1.4, 'versicolor'),
...     (7.6, 3.0, 6.6, 2.1, 'virginica'),
... ]
...
>>> data[0]
(4.7, 3.2, 1.3, 0.2, 'setosa')
>>> data[0][0]
4.7
>>> data[0][4]
'setosa'
>>> data[1]
(7.0, 3.2, 4.7, 1.4, 'versicolor')
>>> data[1][0]
7.0
>>> data[1][4]
'versicolor'
>>> data[2]
(7.6, 3.0, 6.6, 2.1, 'virginica')
>>> data[2][0]
7.6
>>> data[2][4]
'virginica'

8.1.12. Getitem from list[dict]

>>> data = [
...     {'measurements': [4.7, 3.2, 1.3, 0.2], 'species': 'setosa'},
...     {'measurements': [7.0, 3.2, 4.7, 1.4], 'species': 'versicolor'},
...     {'measurements': [7.6, 3.0, 6.6, 2.1], 'species': 'virginica'},
... ]
>>>
>>>
>>> data[0]
{'measurements': [4.7, 3.2, 1.3, 0.2], 'species': 'setosa'}
>>>
>>> data[0]['measurements']
[4.7, 3.2, 1.3, 0.2]
>>>
>>> data[0]['measurements'][2]
1.3
>>>
>>> data[0]['species']
'setosa'

8.1.13. Getitem from list[Sequence]

Get elements from list of sequences:

>>> data = [[1, 2, 3],
...         (4, 5, 6),
...         {7, 8, 9}]
...
>>> data[0]
[1, 2, 3]
>>> data[0][0]
1
>>> data[0][1]
2
>>> data[0][2]
3
>>> data[1]
(4, 5, 6)
>>> data[1][0]
4
>>> data[1][1]
5
>>> data[1][2]
6
>>> data[2] == {7, 8, 9}
True
>>> data[2][0]
Traceback (most recent call last):
TypeError: 'set' object is not subscriptable

8.1.14. Assignments

Code 8.1. Solution
"""
* Assignment: Iterable GetItem Header
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
    1. Define `result: tuple[str]`
    2. Select header from `DATA` (row with index 0)
    3. Write header to `result`
    4. Non-functional requirements:
       a. Use only indexes (`getitem`)
       b. Do not use `str.split()`, `slice`, `for`, `while` or any other
          control-flow statement
    5. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result: tuple[str]`
    2. Wybierz nagłówek z `DATA` (wiersz o indeksie 0)
    3. Zapisz nagłówek do `result`
    4. Wymagania niefunkcjonalne:
       a. Korzystaj tylko z indeksów (`getitem`)
       b. Nie używaj `str.split()`, `slice`, `for`, `while` lub
          jakiejkolwiek innej instrukcji sterującej
    5. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result is not Ellipsis, \
    'Assign your result to variable `result`'
    >>> assert type(result) is tuple, \
    'Variable `result` has invalid type, should be tuple'
    >>> assert len(result) == 5, \
    'Variable `result` length should be 5'

    >>> result
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species')
"""

DATA = [
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
    (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'),
]

# Header from `DATA` (row with index 0)
# type: tuple[str]
result = ...

Code 8.2. Solution
"""
* Assignment: Iterable GetItem Positive
* Type: class assignment
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min

English:
    1. Define `result_a: tuple` with row from `DATA` at index 2
    2. Define `result_b: tuple` with row from `DATA` at index 4
    3. Define `result_c: tuple` with row from `DATA` at index 6
    4. Non-functional requirements:
       a. Use only indexes (`getitem`)
       b. Do not use `str.split()`, `slice`, `for`, `while` or any other
          control-flow statement
    5. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result_a: tuple` z wierszem z `DATA` o indeksie 2
    2. Zdefiniuj `result_b: tuple` z wierszem z `DATA` o indeksie 4
    3. Zdefiniuj `result_c: tuple` z wierszem z `DATA` o indeksie 6
    4. Wymagania niefunkcjonalne:
       a. Korzystaj tylko z indeksów (`getitem`)
       b. Nie używaj `str.split()`, `slice`, `for`, `while` lub
          jakiejkolwiek innej instrukcji sterującej
    5. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result_a is not Ellipsis, \
    'Assign your result to variable `result_a`'
    >>> assert result_b is not Ellipsis, \
    'Assign your result to variable `result_b`'
    >>> assert result_c is not Ellipsis, \
    'Assign your result to variable `result_c`'

    >>> assert type(result_a) is tuple, \
    'Variable `result_a` has invalid type, should be tuple'
    >>> assert type(result_b) is tuple, \
    'Variable `result_b` has invalid type, should be tuple'
    >>> assert type(result_c) is tuple, \
    'Variable `result_c` has invalid type, should be tuple'

    >>> assert len(result_a) == 5, \
    'Variable `result_a` length should be 5'
    >>> assert len(result_b) == 5, \
    'Variable `result_b` length should be 5'
    >>> assert len(result_c) == 5, \
    'Variable `result_c` length should be 5'

    >>> result_a
    (5.1, 3.5, 1.4, 0.2, 'setosa')

    >>> result_b
    (6.3, 2.9, 5.6, 1.8, 'virginica')

    >>> result_c
    (4.7, 3.2, 1.3, 0.2, 'setosa')
"""

DATA = [
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
    (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'),
]

# Row from `DATA` at index 2
# type: tuple[float|str]
result_a = ...

# Row from `DATA` at index 4
# type: tuple[float|str]
result_b = ...

# Row from `DATA` at index 6
# type: tuple[float|str]
result_c = ...

Code 8.3. Solution
"""
* Assignment: Iterable GetItem Negative
* Type: class assignment
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min

English:
    1. Define `result_a: tuple` with row from `DATA` at index -5
    2. Define `result_b: tuple` with row from `DATA` at index -3
    3. Define `result_c: tuple` with row from `DATA` at index -1
    4. Non-functional requirements:
       a. Use only indexes (`getitem`)
       b. Do not use `str.split()`, `slice`, `for`, `while` or any other
          control-flow statement
    5. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result_a: tuple` z wierszem z `DATA` o indeksie -5
    2. Zdefiniuj `result_b: tuple` z wierszem z `DATA` o indeksie -3
    3. Zdefiniuj `result_c: tuple` z wierszem z `DATA` o indeksie -1
    4. Wymagania niefunkcjonalne:
       a. Korzystaj tylko z indeksów (`getitem`)
       b. Nie używaj `str.split()`, `slice`, `for`, `while` lub
          jakiejkolwiek innej instrukcji sterującej
    5. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result_a is not Ellipsis, \
    'Assign your result to variable `result_a`'
    >>> assert result_b is not Ellipsis, \
    'Assign your result to variable `result_b`'
    >>> assert result_c is not Ellipsis, \
    'Assign your result to variable `result_c`'

    >>> assert type(result_a) is tuple, \
    'Variable `result_a` has invalid type, should be tuple'
    >>> assert type(result_b) is tuple, \
    'Variable `result_b` has invalid type, should be tuple'
    >>> assert type(result_c) is tuple, \
    'Variable `result_c` has invalid type, should be tuple'

    >>> assert len(result_a) == 5, \
    'Variable `result_a` length should be 5'
    >>> assert len(result_b) == 5, \
    'Variable `result_b` length should be 5'
    >>> assert len(result_c) == 5, \
    'Variable `result_c` length should be 5'

    >>> result_a
    (5.1, 3.5, 1.4, 0.2, 'setosa')

    >>> result_b
    (6.3, 2.9, 5.6, 1.8, 'virginica')

    >>> result_c
    (4.7, 3.2, 1.3, 0.2, 'setosa')
"""

DATA = [
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
    (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'),
]

# Row from `DATA` at index -5
# type: tuple[float|str]
result_a = ...

# Row from `DATA` at index -3
# type: tuple[float|str]
result_b = ...

# Row from `DATA` at index -1
# type: tuple[float|str]
result_c = ...

Code 8.4. Solution
"""
* Assignment: Iterable GetItem Select
* Type: class assignment
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min

English:
    1. Create `result: list`
       a. Append to `result` a row from `DATA` at index 2
       b. Append to `result` a row from `DATA` at index 4
       c. Append to `result` a row from `DATA` at index -2
    2. Non-functional requirements:
       a. Use only indexes (`getitem`)
       b. Do not use `str.split()`, `slice`, `for`, `while` or any other
          control-flow statement
    3. Run doctests - all must succeed

Polish:
    1. Stwórz `result: list`
       a. Dodaj do `result` wiersz z `DATA` o indeksie 2
       b. Dodaj do `result` wiersz z `DATA` o indeksie 4
       c. Dodaj do `result` wiersz z `DATA` o indeksie -2
    2. Wymagania niefunkcjonalne:
       a. Korzystaj tylko z indeksów (`getitem`)
       b. Nie używaj `str.split()`, `slice`, `for`, `while` lub
          jakiejkolwiek innej instrukcji sterującej
    3. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `list.append()`

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from pprint import pprint

    >>> assert result is not Ellipsis, \
    'Assign your result to variable `result`'
    >>> assert type(result) is list, \
    'Variable `result` has invalid type, should be list'
    >>> assert len(result) == 3, \
    'Variable `result` length should be 6'

    >>> pprint(result)
    [(5.1, 3.5, 1.4, 0.2, 'setosa'),
     (6.3, 2.9, 5.6, 1.8, 'virginica'),
     (6.4, 3.2, 4.5, 1.5, 'versicolor')]
"""

DATA = [
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
    (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'),
]

# Empty list
# type: list[list|tuple|set]
result = ...

# Append row from DATA at index 2
...

# Append row from DATA at index 4
...

# Append row from DATA at index -2
...

Code 8.5. Solution
# TODO: Dopisać testy aby wychwytywały użycie slice oraz [:]
"""
* Assignment: Iterable GetItem Header/Data
* Type: class assignment
* Complexity: easy
* Lines of code: 11 lines
* Time: 5 min

English:
    1. Separate header (first line) from data:
       a. Define `header: tuple[str]` with header
       b. Define `data: list[tuple]` with other data without header
    2. Non-functional requirements:
       a. Use only indexes (`getitem`)
       b. Do not use `str.split()`, `slice`, `for`, `while` or any other
          control-flow statement
       c. You can use copy and paste and/or vertical select `alt`
    3. Run doctests - all must succeed

Polish:
    1. Odseparuj nagłówek (pierwsza linia) od danych:
       a. Zdefiniuj `header: tuple[str]` z nagłówkiem
       b. Zdefiniuj `data: list[tuple]` z danymi bez nagłówka
    2. Wymagania niefunkcjonalne:
       a. Korzystaj tylko z indeksów (`getitem`)
       b. Nie używaj `str.split()`, `slice`, `for`, `while` lub
          jakiejkolwiek innej instrukcji sterującej
       c. Możesz użyć kopiowania i wklejania lub/i zaznaczania pioniwego `alt`
    3. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `list.append()`

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from pprint import pprint

    >>> assert header is not Ellipsis, \
    'Assign your result to variable `header`'
    >>> assert data is not Ellipsis, \
    'Assign your result to variable `data`'
    >>> assert type(header) is tuple, \
    'Variable `header` has invalid type, should be tuple'
    >>> assert all(type(x) is tuple for x in data), \
    'All elements in `data` should be tuple'
    >>> assert header not in data, \
    'Header should not be in `data`'

    >>> pprint(header)
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species')

    >>> pprint(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')]
"""

DATA = [
    ('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
    (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'),
]

# Row at index 0 from DATA
# type: tuple[str]
header = ...

# Rows at all the other indexes from DATA (use only getitem)
# type: list[tuple]
data = ...