4.6. Sequence Unpack GetItem

4.6.1. Rationale

  • Allows to get element from ordered sequence

  • Works with ordered sequences: str, list, tuple

4.6.2. 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'

4.6.3. 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: string index out of range

4.6.4. 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: string index out of range
>>> -0 == 0
True

4.6.5. 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

4.6.6. 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'

4.6.7. 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'

4.6.8. 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'

4.6.9. 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

4.6.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

4.6.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'

4.6.12. 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

4.6.13. Assignments

Code 4.10. Solution
"""
* Assignment: Sequence GetItem Header
* Required: yes
* 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 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 6'

    >>> 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'),
]

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

Code 4.11. Solution
"""
* Assignment: Sequence GetItem Positive
* Required: yes
* 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 result to variable: `result_a`'
    >>> assert result_b is not Ellipsis, \
    'Assign result to variable: `result_b`'
    >>> assert result_c is not Ellipsis, \
    'Assign 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'),
]

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

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

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

Code 4.12. Solution
"""
* Assignment: Sequence GetItem Negative
* Required: yes
* 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 result to variable: `result_a`'
    >>> assert result_b is not Ellipsis, \
    'Assign result to variable: `result_b`'
    >>> assert result_c is not Ellipsis, \
    'Assign 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'),
]

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

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

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

Code 4.13. Solution
"""
* Assignment: Sequence GetItem Select
* Required: yes
* 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

    >>> assert result is not Ellipsis, \
    'Assign 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'

    >>> result  # doctest: +NORMALIZE_WHITESPACE
    [(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'),
]

# list[list|tuple|set]: empty list
result = ...

# append row from DATA at index 2
...

# append row from DATA at index 4
...

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

Code 4.14. Solution
"""
* Assignment: Sequence GetItem Header/Data
* Required: yes
* 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

    >>> assert header is not Ellipsis, \
    'Assign result to variable: `header`'
    >>> assert data is not Ellipsis, \
    'Assign 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`'

    >>> header
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species')

    >>> data  # doctest: +NORMALIZE_WHITESPACE
    [(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'),
     (7.0, 3.2, 4.7, 1.4, 'versicolor'),
     (7.6, 3.0, 6.6, 2.1, 'virginica'),
     (4.9, 3.0, 1.4, 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'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica')]

# tuple[str]: with row at index 0 from DATA
header = ...

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