Exercise 1.a¶

In [2]:
list1 = [1, 2, 3, 4, 5]
list2 = [11, 12, 13, 14, 15]
In [3]:
list_zip = []
for i in range(len(list1)):
    list_zip.append(list1[i])
    list_zip.append(list2[i])
In [4]:
list_zip
Out[4]:
[1, 11, 2, 12, 3, 13, 4, 14, 5, 15]

Limitations: Only works for lists with the same length

The zip function does something similar but not exactly the same, note that we need to convert the object that zipreturns back into a list:

In [5]:
list(zip(list1, list2))
Out[5]:
[(1, 11), (2, 12), (3, 13), (4, 14), (5, 15)]

Exercise 1.b¶

In [6]:
list_odd = [ i for i in list1 + list2 if i % 2 != 0 ]
In [7]:
list_odd
Out[7]:
[1, 3, 5, 11, 13, 15]

Explanation The + operator concatenates to lists and we can create a list on the fly with a for loop inside the list brackets

In [8]:
list1 + list2
Out[8]:
[1, 2, 3, 4, 5, 11, 12, 13, 14, 15]

Exercise 1.c¶

Let us use the zip function this time with a double indexed for loop

In [9]:
list_zip_reverse = []
for i, j in zip(list1[::-1], list2[::-1]):
    list_zip_reverse.append(i)
    list_zip_reverse.append(j)
In [10]:
list_zip_reverse
Out[10]:
[5, 15, 4, 14, 3, 13, 2, 12, 1, 11]

Explanation: Slicing, see numpy section in the notes, can be used for lists as well. To revert a list we do not specify a start nor an end but the step with -1.

Limitations: The shorter list defines the total length

Numpy exercises¶

In [11]:
import numpy as np
In [12]:
x = [1, 2, 3, 5, 7]
In [13]:
X = np.array([1, 2, 3, 5, 7])
In [14]:
Y = np.array([[1.1, 2.1, 3.1], [1.2, 2.2, 3.2]])
In [15]:
v = np.array([1, 2, 3])
In [16]:
Y_sub = Y[:, 1:2]

Slicing will create a new (sub) array¶

In [17]:
Y_sub
Out[17]:
array([[2.1],
       [2.2]])
In [18]:
Y
Out[18]:
array([[1.1, 2.1, 3.1],
       [1.2, 2.2, 3.2]])

Multiplication for numpy arrays¶

Pointwise¶

In [19]:
Y * v
Out[19]:
array([[1.1, 4.2, 9.3],
       [1.2, 4.4, 9.6]])

Matrix Vector Multiplication¶

In [20]:
Y.dot(v)
Out[20]:
array([14.6, 15.2])

How to find help for a function - if google is down ;)¶

In [21]:
help(np.arange)
Help on built-in function arange in module numpy:

arange(...)
    arange([start,] stop[, step,], dtype=None, *, like=None)
    
    Return evenly spaced values within a given interval.
    
    Values are generated within the half-open interval ``[start, stop)``
    (in other words, the interval including `start` but excluding `stop`).
    For integer arguments the function is equivalent to the Python built-in
    `range` function, but returns an ndarray rather than a list.
    
    When using a non-integer step, such as 0.1, the results will often not
    be consistent.  It is better to use `numpy.linspace` for these cases.
    
    Parameters
    ----------
    start : integer or real, optional
        Start of interval.  The interval includes this value.  The default
        start value is 0.
    stop : integer or real
        End of interval.  The interval does not include this value, except
        in some cases where `step` is not an integer and floating point
        round-off affects the length of `out`.
    step : integer or real, optional
        Spacing between values.  For any output `out`, this is the distance
        between two adjacent values, ``out[i+1] - out[i]``.  The default
        step size is 1.  If `step` is specified as a position argument,
        `start` must also be given.
    dtype : dtype
        The type of the output array.  If `dtype` is not given, infer the data
        type from the other input arguments.
    like : array_like
        Reference object to allow the creation of arrays which are not
        NumPy arrays. If an array-like passed in as ``like`` supports
        the ``__array_function__`` protocol, the result will be defined
        by it. In this case, it ensures the creation of an array object
        compatible with that passed in via this argument.
    
        .. versionadded:: 1.20.0
    
    Returns
    -------
    arange : ndarray
        Array of evenly spaced values.
    
        For floating point arguments, the length of the result is
        ``ceil((stop - start)/step)``.  Because of floating point overflow,
        this rule may result in the last element of `out` being greater
        than `stop`.
    
    See Also
    --------
    numpy.linspace : Evenly spaced numbers with careful handling of endpoints.
    numpy.ogrid: Arrays of evenly spaced numbers in N-dimensions.
    numpy.mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions.
    
    Examples
    --------
    >>> np.arange(3)
    array([0, 1, 2])
    >>> np.arange(3.0)
    array([ 0.,  1.,  2.])
    >>> np.arange(3,7)
    array([3, 4, 5, 6])
    >>> np.arange(3,7,2)
    array([3, 5])

In [22]:
A = np.reshape(np.arange(20), (4, 5))

It is also possible to apply the reshape function directly to the array

In [23]:
A = np.arange(20).reshape(4, 5)
In [24]:
A[1, 2]
Out[24]:
7
In [25]:
A[0::2, 1::2]
Out[25]:
array([[ 1,  3],
       [11, 13]])

A module can have a submodule, which might contain a function¶

In [26]:
np.random.rand()
Out[26]:
0.40957911630332644