Python Built-in Data Structures

This section provides a brief overview of

  • The built-in datastructures in Python - list, tuples, and dictionaries
  • For loop

Lists

You can use lists to store a sequence of values. A list is a collection of references to Python data objects. Note than in Python list indexes start at 0 (similar to C or C++). Different ways of creating lists are shown below

In [1]:
a = [] # creates an empty list
In [2]:
a = [8, 9, 10] # creates a list of three elements
b = [10, 7, 18, "Avi"]

List indices start at 0 from left with positive index. List indices start at -1 from right for negative index.

In [3]:
a[1] # Prints the second element
Out[3]:
9
In [4]:
a[-2] # Prints the second element
Out[4]:
9

Slicing

You can access sub-lists through the colon operator. This process is called slicing.

In [5]:
a = [10, 7, 14, 27, 21]
a[2:] # Prints everything to the right of 14 and includes 14
Out[5]:
[14, 27, 21]
In [6]:
a[:3] # Prints everything to the left of 27
Out[6]:
[10, 7, 14]
In [7]:
a[2:4] # Prints sub-lists containing second and third index
Out[7]:
[14, 27]
In [8]:
a[2:-1] # Same output as above
Out[8]:
[14, 27]

Methods

The symbol + and * are concatenation operators. There are several methods associated with lists.

In [9]:
a = [10, 7, 14]
a = a*2 # output should be [10, 7, 14, 10, 7, 14]
print(a)
[10, 7, 14, 10, 7, 14]
In [10]:
c = [a]*2 # Note the difference
print(c)
[[10, 7, 14, 10, 7, 14], [10, 7, 14, 10, 7, 14]]
In [11]:
a = [10, 7, 14]
b = [5, 8, 11]
a = a + b # output should be [10, 7, 14, 5, 8, 11]
print(a)
[10, 7, 14, 5, 8, 11]
In [12]:
len(a) #prints the length of the list
Out[12]:
6
In [13]:
a.append(20) #Adds 20 to the end of the list
a
Out[13]:
[10, 7, 14, 5, 8, 11, 20]
In [14]:
a.pop() # Deletes the last element
a
Out[14]:
[10, 7, 14, 5, 8, 11]
In [15]:
a.reverse() # reverses the list
a
Out[15]:
[11, 8, 5, 14, 7, 10]
In [16]:
a.sort() #sorts the list
a
Out[16]:
[5, 7, 8, 10, 11, 14]
In [17]:
a.remove(11) # removes 11
a
Out[17]:
[5, 7, 8, 10, 14]
In [18]:
20 in a # Returns a boolean value for the check if element 20 is in list b
Out[18]:
False
In [19]:
10 in a
Out[19]:
True

range(start, stop, stepsize) can be used to generate a sequence of numbers. list(range(start, stop, stepsize)) can be used to create a list comprising from the sequence. Note that the number corresponding to stop is not a part of the list.

In [20]:
a = list(range(10,20,2))
a
Out[20]:
[10, 12, 14, 16, 18]

You can create lists of non-integer objects also.

In [21]:
cities= ["Nashville", "Austin", "Pittsburgh"]
cities
Out[21]:
['Nashville', 'Austin', 'Pittsburgh']

Lists can contain objects of different type.

In [22]:
d = [5, 6, "seven", 8, 9]
d
Out[22]:
[5, 6, 'seven', 8, 9]
In [23]:
del d[2] #removes the third element
d
Out[23]:
[5, 6, 8, 9]

References

Lists are a collection of references to Python data objects.

In [24]:
a = [5, 8 , 12]
b = a
print("a = ", a) # output is [5, 8, 12]
print("b = ", b) # output is [5, 8, 12]
a.append(4)
print("a = ", a) # output is [5, 8, 12, 4]
print("b = ", b) # output is [5, 8, 12, 4]
a =  [5, 8, 12]
b =  [5, 8, 12]
a =  [5, 8, 12, 4]
b =  [5, 8, 12, 4]

When we run the command

In [25]:
a = [5, 8 , 12]
b = a

We are essentially creating two references.

List and  References

In [26]:
a.append(4)
print("a = ", a)
print("b = ", b)
a =  [5, 8, 12, 4]
b =  [5, 8, 12, 4]

List and  References

You can use the slicing operator to make independent copies.

In [27]:
a = [5, 8 , 12]
b = a[:]
print("a = ", a) # output is [5, 8, 12]
print("b = ", b) # output is [5, 8, 12]
a.append(4)
print("a = ", a) # output is [5, 8, 12, 4]
print("b = ", b) # output is [5, 8, 12]
a =  [5, 8, 12]
b =  [5, 8, 12]
a =  [5, 8, 12, 4]
b =  [5, 8, 12]

Another way is to use the deepcopy command.

In [28]:
from copy import deepcopy
a = [5, 8 , 12]
b = deepcopy(a)
print("a = ", a) # output is [5, 8, 12]
print("b = ", b) # output is [5, 8, 12]
a.append(4)
print("a = ", a) # output is [5, 8, 12, 4]
print("b = ", b) # output is [5, 8, 12]
a =  [5, 8, 12]
b =  [5, 8, 12]
a =  [5, 8, 12, 4]
b =  [5, 8, 12]

Lists can be two dimensional.

In [29]:
twodlist = [[1, 2, 3],[11, 12, 13],[21, 22, 23]]
twodlist[1]
Out[29]:
[11, 12, 13]
In [30]:
twodlist[1][1]
Out[30]:
12

Similarly, we can define three, four, or five dimensional lists. Be careful, when you use * to create two D lists as you are creating references and not copies

In [31]:
b = [1,2]
A = [b]*3
print(A)
[[1, 2], [1, 2], [1, 2]]
In [32]:
b[0] = 5
A[0][1] = 3
print(A)
[[5, 3], [5, 3], [5, 3]]

Pay close attention to how the list A has changed.

Tuples and Dictionaries

Tuples are like lists but with two main differences:

  • You cannot change or delete elements of a tuple once created. Tuples are immutable objects.
  • Tuples use parenthesis whereas lists use square brackets.

Tuples are faster than lists. However, the speed gains might not be significant for our applications. Therefore, stick to lists whenever possible.

In [33]:
e = (3, 8, 11, 7) # creates a tuple
e
Out[33]:
(3, 8, 11, 7)
In [34]:
e[2] # we use square brackets to access elements of tuples
Out[34]:
11
In [35]:
e[2] = 12 # There should be an error message
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-6b879ed945e7> in <module>()
----> 1 e[2] = 12 # There should be an error message

TypeError: 'tuple' object does not support item assignment

Dictionaries can be used to create maps or unordered collection of objects in Python. In dictionaries, keys are associated with values. The keys are separated from their values using colon. Each key-value item is separated using comma.

In [36]:
pop = {'Nashville': 200, 'Austin': 500, 'Pittsburgh': 300} 
In [37]:
pop.keys()
Out[37]:
dict_keys(['Nashville', 'Austin', 'Pittsburgh'])
In [38]:
pop.values()
Out[38]:
dict_values([200, 500, 300])

The keys and values can be converted to lists using list() function.

In [39]:
list(pop.keys())
Out[39]:
['Nashville', 'Austin', 'Pittsburgh']
In [40]:
pop['Nashville']
Out[40]:
200
In [41]:
'Austin' in pop
Out[41]:
True

Python For Loops

For loops can be used to iterate over elements in lists, tuples, or dictionaries. Indents used to identify code blocks.

In [42]:
a = [1, 3, 5, 7]
for i in a: # For each element in list a
    print(i*i)
1
9
25
49
In [43]:
for i in range(20, 30):
    if (i % 2 == 0):
        print(i)
20
22
24
26
28

For loops can be nested.

In [44]:
for i in range(1, 5):
    for j in range(10,15):
        print(i*j) 
10
11
12
13
14
20
22
24
26
28
30
33
36
39
42
40
44
48
52
56

When you are dealing with non-numeric lists or list lengths which keep changing during implementation you can use range(len(listname)).

In [45]:
cities = ["Nashville", "Austin", "Morgantown", "Portland"]
for i in range(len(cities)):
    print(i,cities[i])
0 Nashville
1 Austin
2 Morgantown
3 Portland

Another way is using enumerate.

In [46]:
cities = ["Nashville", "Austin", "Morgantown", "Portland"]
for num, name in enumerate(cities):
    print(num, name)
0 Nashville
1 Austin
2 Morgantown
3 Portland

If you want the index to start from a number other than 0.

In [47]:
cities = ["Nashville", "Austin", "Morgantown", "Portland"]
for num, name in enumerate(cities, 1):
    print(num, name)
1 Nashville
2 Austin
3 Morgantown
4 Portland

The zip command can be used to pairwise merge lists of equal lengths.

In [48]:
a = [1, 2, 3]
b = [10, 11, 12]
c = zip(a,b)
print(list(c))
[(1, 10), (2, 11), (3, 12)]

If you want to go through two lists in a for loop.

In [49]:
cities = ["Nashville", "Austin", "Morgantown", "Portland"]
population = [200, 500, 100, 400]
for name, popul in zip(cities,population):
    print(name, popul)
Nashville 200
Austin 500
Morgantown 100
Portland 400

In dictionaries, the default is to iterate through the keys.

In [50]:
pop = {'Nashville': 200, 'Austin': 500, 'Pittsburgh': 300} 
for i in pop:
    print(i)
Nashville
Austin
Pittsburgh
In [51]:
for i in pop.values():
    print(i)
200
500
300
In [52]:
for i,j in pop.items():
    print(i,j)
Nashville 200
Austin 500
Pittsburgh 300

For loops and conditional expressions can be used to create lists conveniently. This is called list comprehension.

In [53]:
a = [i for i in range(3)]
a
Out[53]:
[0, 1, 2]
In [54]:
a = [i*2 for i in [10, 20, 25]]
a
Out[54]:
[20, 40, 50]
In [55]:
a = [[i,j] for i in [1, 2, 3] for j in [10, 11, 12]]
a
Out[55]:
[[1, 10],
 [1, 11],
 [1, 12],
 [2, 10],
 [2, 11],
 [2, 12],
 [3, 10],
 [3, 11],
 [3, 12]]
In [56]:
a = [i for i in range(5) if(i%2 == 0)]
a
Out[56]:
[0, 2, 4]
In [57]:
c = [20, 10, 50]
d = [ 5, 25, 40]
e = [max(i) for i in zip(c,d)]
e
Out[57]:
[20, 25, 50]