Concept of array

You know how to store single element into a variable, but if you want to storage multiple variables in a single one (something like the age and height of a person), you need to step up to the next level. In other languages an array is a data structure with fixed size and fixed type of data that can be stored inside of it (there is also more stuff as the vectors in C++).

Here in python there are 2 types of data structures that allows you to store multiple variables (can be different types) inside of them. Both are 0-indexed, that means you can access to its elements based on their positions inside of the data structure, and that its first element has index 0, the second has index 1 and so on. Now let's see their differences.

Tuples (immutable arrays)

The tuples are immutable, that means that once they have been created, you cannot change their values, its really helpful if you don't want them to change. You can use them enclose with "()" or without them, but it is a recomendation to use them.

A = tuple()         # A = (), an empty tuple
B = (1, 2, 3)       # B = (1, 2, 3)
C = '4', '5', '6'   # C = ('4', '5', '6')
D = B*3             # D = (1, 2, 3, 1, 2, 3, 1, 2, 3)
E = A+B+C           # E = (1, 2, 3, '4', '5', '6')
F = (A, B, C)       # F = ((), (1, 2, 3), ('4', '5', '6'))
G = ((1, 2, 3),
    (4, 5, 6, 7))   # F = ((1, 2, 3), (4, 5, 6, 7))

# A[0] will give an error because A does not have any element at index 0
B[0]                # 1
B[2]                # 3, A[3] will give you an error "out of range"
B[-1]               # 3, a way to reach the last element
E[0:5]              # (1, 2, 3, '4', '5')
G[0]                # (1, 2, 3)
G[1][0]             # 4, the first element of the second tuple

Tuple methods

Method Description
count(x) Returns how many items are inside the tuple that are the same than "x"
index(x) Returns the first index where "x" appears. It gives an error if "x" is not inside of the tuple
A = ()              # same as A = tuple()      
B = (5, 1, 2, 3, 4) 
C = ((1, 2, 3),(5, 6, 7))

# Some functions applied to the tuples
type(A)             # Returns < class 'tuple' >
len(A)              # The length of A is 0, as it has 0 element
len(B)              # The length of B is 5, as it has 5 integers
len(C)              # The length of C is 2, as it has 2 tuples
del A               # deletes the tuple A

# Tuple methods
B.count('4')        # 0, there is not any '4' in the tuple
B.count(4)          # 1, there is just one 4
B.index(5)          # 0, 5 its an index 0

Some uses

The tuple itself is immutable, but you can create a new tuple out of another one. Also, you can swap 2 elements using tuples.

A = (1, 'two', 3)   # A = (1, 'two', 3)
B = (A[0], 2, A[1]) # B = (1, 2, 3)

C, D, E = B         # C = 1, D = 2, E = 3
F, G = A, B         # F = (1, 'two', 3), F = (1, 2, 3)
A, B = B, A         # Internally for python, these are tuples and we just swap them
# A = (1, 2, 3)
# B = (1, 'two', 3)

Lists (mutable arrays)

Basically the same as a tuple, but you can change its values, that allows you to do a lot of more things.

A = list()          # A = [], an empty list
B = [1, 'two', 3]   # B = [1, 'two', 3]
C = ['4', '5', '6'] # C = ['4', '5', '6']
D = B*3             # D = [1, 'two', 3, 1, 'two', 3, 1, 'two', 3]
E = A+B+C           # E = [1, 'two', 3, '4', '5', '6']
F = [A, B, C]       # F = [[], [1, 'two', 3], ['4', '5', '6']]
G = [[1, 2, 3],
    [4, 5, 6, 7]]   # F = [[1, 2, 3], [4, 5, 6, 7]]

# A[0] will give an error because A does not have any element at index 0
B[0]                # 1
B[2]                # 3, A[3] will give you an error "out of range"
B[-1]               # 3, a way to reach the last element
E[0:5]              # [1, 'two', 3, '4', '5']
G[0]                # [1, 2, 3]
G[1][0]             # 4, the first element of the second list

# Mutable array
B[1]                # 'two'
B[1] = 2            # B = [1, 2, 3]    
C += ['7']          # C = ['4', '5', '6', '7']
# C += '7' gives an error because you cannot sum ints with lists

List methods

Method Description
count(x) Returns how many elements inside of the string are the same than "x"
index(x) Returns the first index where "x" appears. It gives an error if "x" is not inside of the list
append(x) Adds "x" at the end of the list
insert(x,pos) Adds "x" at the specified position. Default "pos" is -1 (insert at the end)
extend(X) Adds all the elements "X", to the end of the current list
copy() Returns a copy of the current list (Same as Y = X[:])
pop(pos) Removes the element at the specified position and returns it. Default "pos" is -1 (remove the last)
remove(x) Removes the first specified value "x"
clear() Removes all the elements from the list
reverse() Reverses the order of the list (X = X[::-1])
sort() Sorts the list in place
A = []              # same as A = list()
B = [4, 1, 2, 3]
C = [[1, 2, 3],[5, 6, 7]]

# Some functions applied to the lists
D = sorted(B)       # D = [1, 2, 3, 4], B = [4, 1, 2, 3]
type(A)             # Returns < class 'list' >
len(A)              # The length of A is 0, as it has 0 element
len(B)              # The length of B is 4, as it has 4 integers
len(C)              # The length of C is 2, as it has 2 lists
del A               # deletes the list A
del B[0]            # deletes the first index of B, B = [1, 2, 3]

# List methods
C.count(1)          # 0, there is no index with 1 as a single element in C
C.count([1,2,3])    # 1, there is one index in C
B.index(3)          # 2, 3 its an index 2
B.append(4)         # B = [1, 2, 3, 4]
B.append([5,6])     # B = [1, 2, 3, 4, [5, 6]]
B.insert(0,0)       # B = [0, 1, 2, 3, 4, [5, 6]]
B.extend([7,8])     # B = [0, 1, 2, 3, 4, [5, 6], 7, 8]
E = B.copy()        # E = [0, 1, 2, 3, 4, [5, 6], 7, 8]
F = B.pop()         # F = 8, B = [0, 1, 2, 3, 4, [5, 6], 7]
B.remove([5,6])     # B = [0, 1, 2, 3, 4, 7]
E.clear()           # E = []
B.reverse()         # B = [7, 4, 3, 2, 1, 0]
B.sort()            # B = [0, 1, 2, 3, 4, 7]

Memory conflicts

Watch out for the way you declare a list out of another list, one way links both lists (changes in one list affect the other) and the other creates a copy of the main list. Both ways are useful.

A = [1,2,3]
B = [4,5,6]

# Linked lists way
C = [A,B]               # C = [[1, 2, 3], [4, 5, 6]]
A[0] = 0                # A = [0, 2, 3], C = [[0, 2, 3], [4, 5, 6]]

# Copy lists way
D = [A[:], B.copy()]    # D = [[0, 2, 3], [4, 5, 6]]
A[0] = 1                # A = [1, 2, 3], D = [[0, 2, 3], [4, 5, 6]]

Assigning multiple elements from a list or tuple

You can assign the elements from a list or tuple directly to variables, but you must be really careful to have the same amount of elements inside of the data type and the amount of variables you are using.

"""
You can extract elements from a data type, 
but take care to have the same amount of elements in both sides:

arr = [a1, a2, a3, ... an]

# Parentheses are optional
(x1, x2, x3, ... xn) = arr    # x1=a1, x2=a2, x3=a3, ... xn=an
"""

person = ('Albert', 'Einstein')
primes = [2,3,5,7,11]
arrays = [[0], [1,2], [3,4,5], [6,7,8,9]]

name, lastname = person
# name = 'Albert'
# lastname = 'Einstein'

p1, p2, p3, p4, p5 = primes
# p1 = 2
# p2 = 3
# P3 = 5
# p4 = 7
# p5 = 11

l1, l2, l3, l4 = arrays
# l1 = [0]
# l2 = [1,2]
# l3 = [3,4,5]
# l4 = [6,7,8,9]