3.1. Sequence List

3.1.1. Rationale

  • Mutable - can add, remove, and modify items

3.1.2. Definition

Defining empty list with [] is used more often, but list() is more explicit:

>>> data = list()
>>> data = []

Can store elements of any types:

>>> data = [1, 2, 3]
>>> data = [1.1, 2.2, 3.3]
>>> data = [True, False]
>>> data = ['a', 'b', 'c']
>>> data = ['a', 1, 2.2, True, None]

Brackets are required

>>> data = [1, 2, 3]

Comma after last element of a one element list is optional

>>> data = [1,]
>>> type(data)
<class 'list'>
>>> data = [1]
>>> type(data)
<class 'list'>

3.1.3. Type Casting

Builtin function list() converts argument to list

>>> data = 'abcd'
>>> list(data)
['a', 'b', 'c', 'd']
>>> data = ['a', 'b', 'c', 'd']
>>> list(data)
['a', 'b', 'c', 'd']
>>> data = ('a', 'b', 'c', 'd')
>>> list(data)
['a', 'b', 'c', 'd']
>>> list(1, 2, 3, 4)
Traceback (most recent call last):
TypeError: list expected at most 1 argument, got 4

3.1.4. GetItem

  • More information in Sequence GetItem

  • More information in Sequence Slice

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

3.1.5. Set Item

>>> data = ['a', 'b', 'c', 'd']
>>> data[0] = 'x'
>>>
>>> print(data)
['x', 'b', 'c', 'd']
>>> data = ['a', 'b', 'c', 'd']
>>> data[4] = 'x'
Traceback (most recent call last):
IndexError: list assignment index out of range

3.1.6. Del Item

>>> data = ['a', 'b', 'c', 'd']
>>> del data[3]
>>>
>>> print(data)
['a', 'b', 'c']
>>> data = ['a', 'b', 'c', 'd']
>>> value = data.pop()
>>>
>>> data
['a', 'b', 'c']
>>> value
'd'

3.1.7. Append

  • list + list

  • list += list

  • list.extend()

  • list.append()

>>> data = [1, 2]
>>> data = data + [3, 4]
>>>
>>> print(data)
[1, 2, 3, 4]
>>> data = [1, 2]
>>> data += [3, 4]
>>>
>>> print(data)
[1, 2, 3, 4]
>>> data = [1, 2]
>>> data.extend([3, 4])
>>>
>>> print(data)
[1, 2, 3, 4]
>>> data = [1, 2]
>>> data.append(3)
>>>
>>> print(data)
[1, 2, 3]
>>> data = [1, 2]
>>> data.append([3, 4])
>>>
>>> print(data)
[1, 2, [3, 4]]

3.1.8. Insert

  • Insert at specific position

>>> data = ['a', 'b', 'c', 'd']
>>> data.insert(0, 'x')
>>>
>>> print(data)
['x', 'a', 'b', 'c', 'd']
>>> data = ['a', 'b', 'c', 'd']
>>> data.insert(1, 'x')
>>>
>>> print(data)
['a', 'x', 'b', 'c', 'd']

3.1.9. Sort vs Sorted

Timsort is a hybrid stable sorting algorithm, derived from merge sort and insertion sort, designed to perform well on many kinds of real-world data. It was implemented by Tim Peters in 2002 for use in the Python programming language. The algorithm finds subsequences of the data that are already ordered (runs) and uses them to sort the remainder more efficiently. This is done by merging runs until certain criteria are fulfilled. Timsort has been Python's standard sorting algorithm since version 2.3. It is also used to sort arrays of non-primitive type in Java SE 7, on the Android platform, in GNU Octave, on V8, Swift, and Rust. [timsort]

  • Worst-case performance: \(O(n\log{n})\)

  • Best-case performance: \(O(n)\)

  • Average performance: \(O(n\log{n})\)

  • Worst-case space complexity: \(O(n)\)

  • sorted() - Returns sorted list, do not modify the original

  • list.sort() - Changes object permanently, returns None

>>> a = [3, 1, 2]
>>> b = sorted(a)
>>>
>>> print(a)
[3, 1, 2]
>>>
>>> print(b)
[1, 2, 3]
>>> a = [3, 1, 2]
>>> b = a.sort()
>>>
>>> print(a)
[1, 2, 3]
>>>
>>> print(b)
None

3.1.10. Method Chaining

>>> data = [3, 1, 2]
>>> data.sort()
>>> data.append(4)
>>>
>>> print(data)
[1, 2, 3, 4]
>>> data = [3, 1, 2]
>>>
>>> data.sort().append(4)
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'append'

3.1.11. Built-in Functions

  • min() - Minimal value

  • max() - Maximal value

  • sum() - Sum of elements

  • len() - Length of a list

  • all() - All values are True

  • any() - Any values is True

>>> data = [2, 0, 1]
>>>
>>> min(data)
0
>>> max(data)
2
>>> sum(data)
3
>>> len(data)
3
>>> data = [True, False, True]
>>>
>>> any(data)
True
>>> all(data)
False

3.1.12. Assignments

Code 3.1. Solution
"""
* Assignment: Sequence List Create
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min

English:
    1. Create list `result` with elements:
        a. `'a'`
        b. `1`
        c. `2.2`
    2. Compare result with "Tests" section (see below)

Polish:
    1. Stwórz listę `result` z elementami:
        a. `'a'`
        b. `1`
        c. `2.2`
    2. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> type(result)
    <class 'list'>
    >>> len(result)
    3
    >>> 'a' in result
    True
    >>> 1 in result
    True
    >>> 2.2 in result
    True
"""

# Given
result: list  # with 'a' and 1 and 2.2

Code 3.2. Solution
"""
* Assignment: Sequence List Many
* Complexity: easy
* Lines of code: 3 lines
* Time: 5 min

English:
    1. Use data from "Given" section (see below)
    2. Create list `a` with data from row 1
    3. Create list `b` with data from row 2
    4. Create list `c` with data from row 3
    5. Rewrite data manually:
        a. Do not automate by writing code
        b. Do not use `str.split()`, `slice`, `getitem`, `for`, `while` or any other control-flow statement
        c. Objective is to learn the syntax, not automation
        d. Convert numerical values to float (manually)
    6. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Stwórz listę `a` z danymi z wiersza 1
    3. Stwórz listę `b` z danymi z wiersza 2
    4. Stwórz listę `c` z danymi z wiersza 3
    5. Przepisz dane ręcznie:
        a. Nie automatyzuj pisząc kod
        b. Nie używaj `str.split()`, `slice`, `getitem`, `for`, `while` lub jakiejkolwiek innej instrukcji sterującej
        c. Celem jest nauka składni, a nie automatyzacja
        d. Przekonwertuj wartości numeryczne do float (ręcznie)
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> type(a)
    <class 'list'>
    >>> type(b)
    <class 'list'>
    >>> type(c)
    <class 'list'>
    >>> len(a)
    5
    >>> len(b)
    5
    >>> len(c)
    5
    >>> (5.8 in a
    ...  and 2.7 in a
    ...  and 5.1 in a
    ...  and 1.9 in a
    ...  and 'virginica' in a)
    True
    >>> (5.1 in b
    ...  and 3.5 in b
    ...  and 1.4 in b
    ...  and 0.2 in b
    ...  and 'setosa' in b)
    True
    >>> (5.7 in c
    ...  and 2.8 in c
    ...  and 4.1 in c
    ...  and 1.3 in c
    ...  and 'versicolor' in c)
    True
"""

# Given
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']

a: list  # with data from row 1
b: list  # with data from row 2
c: list  # with data from row 3

Code 3.3. Solution
"""
* Assignment: Sequence List Modify
* Complexity: easy
* Lines of code: 3 lines
* Time: 5 min

English:
    1. Use data from "Given" section (see below)
    2. Insert at the begin of `a` last element popped from `b`
    3. Append to the `b` last element popped from `a`
    4. For getting elements use `list.pop()`
    5. From list `c` using `del` delete last element
    6. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Na początek `a` wstaw ostatni element wyciągnięty z `b`
    3. Na koniec `b` wstaw ostatni element wyciągnięty z `a`
    4. Do wyciągnięcia używaj `list.pop()`
    5. Z listy `c` za pomocą `del` usuń ostatni element
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> type(a)
    <class 'list'>
    >>> type(b)
    <class 'list'>
    >>> type(c)
    <class 'list'>
    >>> a
    ['versicolor', 4.7, 3.2, 1.3, 0.2]
    >>> b
    [7.0, 3.2, 4.7, 1.4, 'setosa']
    >>> c
    [7.6, 3.0, 6.6, 2.1]
"""

# Given
a = [4.7, 3.2, 1.3, 0.2, 'setosa']
b = [7.0, 3.2, 4.7, 1.4, 'versicolor']
c = [7.6, 3.0, 6.6, 2.1, 'virginica']