1.13 Some Python Concepts

1.13.1 Mutability

This discussion is not necessary when you start using Python. Come back to this only when you have a need to understand the difference between mutable and immutable objects.

A useful explanation about variables in Python by Ned Batchelder can be found here.

Recall that everything is Python is an objectI.e. (Loosely) has attributes and methonds that can be accessed with the . operator. and that an object has an id attached to itThis is the ‘location’ that Python is storing the information. You can access this using the internal function id().. Each of these objects also have another important property called mutabilityThis is related to how Python internally allocated memory to these objects.. Some objects (e.g. integers) are immutable and some other object (e.g. lists) are mutable. But what does this mean?

1.13.1.1 Immutable

Changing an immutable objects always leads to a new object.

Code Note Comment
x = 5 id(5) = 4381985264
id(x) = 4381985264
x is viewing the immutable object (integer) 5
x = x + 1 id(6) = 4381985296
id(x) = 4381985296
x is now viewing the immutable object (integer) 6

1.13.1.2 Mutable

Mutable objects can be changed in-place without changing the id.

Code Note Comment
x = [1,2] id(x) = 4511976776 x is viewing the mutable object (list) [1,2]
x += [3,5] id(x) = 4511976776 x is now viewing the same mutable object (list) [1,2,3,4]
The list has grown in-placex = x + [3,4] is not an in-place operation.

1.13.2 Data Types

Type Numpy Info Size (bytes) Example
integer int8 From -128 to +127 1 \(-1,0,1\)
int16 from -32768 to + 32767 2 \(-1,0,1\)
unsigned integer uint8 From 0 to 255 1 \(0,1,2,3\)
uint16 From 0 to 65535 2 0,1,2,3
float `float16 Precision to 0.001 2 \(\pm 3.14\)
float32 Precision to 0.00001 4 \(\pm 3.14\)
complex complex64 8 \(1+j\)
boolean bool 1
string 'hahaha'
import numpy as np

# A list of some possible data types
my_types = ['int8', 'uint8',
            'int16', 'uint16',
            'float16', 'float32',
            'complex']

# Some numbers
numbers = np.array([-300, -100,
                    -np.pi, 0, np.pi,
                    10, 100, 70000])

print(f'Original\t:\t{numbers}')                    # Print the original

# Convert a into the various types and print
# Original  :   [-3.00000000e+02 -1.00000000e+02 -3.14159265e+00  0.00000000e+00
#   3.14159265e+00  1.00000000e+01  1.00000000e+02  7.00000000e+04]
for typ in my_types:
    number_converted = numbers.astype(typ)
    print(f'{typ}\t:\t{number_converted}')
# int8  :   [ -44 -100   -3    0    3   10  100  112]
# uint8 :   [212 156 253   0   3  10 100 112]
# int16 :   [-300 -100   -3    0    3   10  100 4464]
# uint16    :   [65236 65436 65533     0     3    10   100  4464]
# float16   :   [-300.   -100.     -3.14    0.      3.14   10.    100.       inf]
# float32   :   [-3.0000000e+02 -1.0000000e+02 -3.1415927e+00  0.0000000e+00
#   3.1415927e+00  1.0000000e+01  1.0000000e+02  7.0000000e+04]
# complex   :   [-3.00000000e+02+0.j -1.00000000e+02+0.j -3.14159265e+00+0.j
#   0.00000000e+00+0.j  3.14159265e+00+0.j  1.00000000e+01+0.j
#   1.00000000e+02+0.j  7.00000000e+04+0.j]