Basic data structures#
Lists#
Lists are heterogeneous and dynamic arrays which allows to group data which are not necessarily of the same type. Lists are very easy to use but, be careful, they are not the fastest struct you can use for numerical computations.
A list is declared using the [ ]
characters, and its elements are separated by ,
.
NOTE: Lists are NOT recommended for numerical work, it is better to use numpy arrays.
See: https://quickref.me/python#python-lists
xdata = [] # declares empty list
print (xdata)
xdata = [1,2, 3, 6.5, 'hello'] # heterogeneous list
print (xdata)
[]
[1, 2, 3, 6.5, 'hello']
# Access by indices
print (xdata[0])
print (xdata[3])
print (xdata[4])
print (xdata[4][3]) # Does this make sense?
1
6.5
hello
l
# Slicing operations [start=0, end, increment]
print (xdata[0:2])
print (xdata[0:3])
print (xdata[0:4:1])
print (xdata[:4:2])
print (xdata[::1])
print (xdata[::-1]) # inverse order
print (xdata[:-1])
[1, 2]
[1, 2, 3]
[1, 2, 3, 6.5]
[1, 3]
[1, 2, 3, 6.5, 'hello']
['hello', 6.5, 3, 2, 1]
[1, 2, 3, 6.5]
# From other lists
a = [2,3,4]
b = [3,4,5]
c = a + b
print (c) # Concatenate the lists
print (2*c) # duplicate the list
[2, 3, 4, 3, 4, 5]
[2, 3, 4, 3, 4, 5, 2, 3, 4, 3, 4, 5]
# Check memory address
a.append(55)
print(f"{id(a[0])}, {id(a[1])}, {id(a[2])}, {id(a[3])}")
140313412033832, 140313412033864, 140313412033896, 140313412035528
import numpy as np
a = np.array([2,3,4])
b = np.array([3,4,5])
c = a + b
print (c)
print(2*c)
[5 7 9]
[10 14 18]
# List comprehension
squares = [x**2 for x in range(0, 10)]
print(squares)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Exercises#
def printreversed(l):
# YOUR CODE HERE
raise NotImplementedError()
printreversed([1, 2, 3])
printreversed([1, 2, 3, 4 , "hola", "mundo"])
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
Cell In[9], line 1
----> 1 printreversed([1, 2, 3])
2 printreversed([1, 2, 3, 4 , "hola", "mundo"])
Cell In[8], line 3, in printreversed(l)
1 def printreversed(l):
2 # YOUR CODE HERE
----> 3 raise NotImplementedError()
NotImplementedError:
import numpy as np
def primefactors(n):
# YOUR CODE HERE
raise NotImplementedError()
# def primefactors(n):
# """
# From chatgpt
# """
# factors = []
# divisor = 2
# while divisor <= n:
# if n % divisor == 0:
# factors.append(divisor)
# n /= divisor
# else:
# divisor += 1
# return factors
def isprime(n):
# YOUR CODE HERE
raise NotImplementedError()
print(primefactors(2))
print(primefactors(8))
print(primefactors(10))
print(primefactors(201))
print(primefactors(97))
print(primefactors(1213427))
print(primefactors(1213428))
print(primefactors(1213428987543096))
import numpy as np
def stats(data):
# YOUR CODE HERE
raise NotImplementedError()
stats([1, 2, 3.5])
Tuples#
A tuple is like a list, but is inmutable, it cannot change. It is declared by using ()
.
a = (1, 2)
print (a)
print (a[0])
# a[1] = 4 # error, tuple is inmutable
b = () # empty tuple
print (b)
You can use tuples to unpack data from functions returning several results
def func(x, y) :
return x + y, x-y # returns a tuple
a, b = func(1, 2)
print (a, b)
Classes#
Python is an object oriented language. Everything is an object. You can also create new types by using classes, after defining their attributes and methods. When creating classes, you should is the self
keyword, which is the analogous to the pointer this
in c++. Let’s create a class for a point.
class Point2D :
"""This is a doctring. This allows to embed documentation inside the class definition.
You can split it
across several lines.
"""
def __init__(self, x = 0, y = 0):
""" This is the constructor"""
self.x_ = x # attribute x_
self.y_ = y # attribute y_
def coordinates(self):
return self.x_, self.y_
def __str__(self):
"""Cast method to convert to string"""
return (f"Coordinates : ( {self.x_:25.16e}, {self.y_:25.16e} )")
p1 = Point2D() # constructs a point with default internal attributes
print (p1) # Uses the str cast method
p2 = Point2D(2, -3)
print (p2)
%%html
<iframe width="800" height="500" frameborder="0" src="https://pythontutor.com/iframe-embed.html#code=class%20Point2D%20%3A%0A%20%20%20%20%22%22%22This%20is%20a%20doctring.%20This%20allows%20to%20embed%20documentation%20inside%20the%20class%20definition.%0A%20%20%20%20You%20can%20split%20it%20%0A%20%20%20%20across%20several%20lines.%0A%20%20%20%20%22%22%22%0A%20%20%20%20def%20__init__%28self,%20x%20%3D%200,%20y%20%3D%200%29%3A%20%0A%20%20%20%20%20%20%20%20%22%22%22%20This%20is%20the%20constructor%22%22%22%0A%20%20%20%20%20%20%20%20self.x_%20%3D%20x%20%23%20attribute%20x_%0A%20%20%20%20%20%20%20%20self.y_%20%3D%20y%20%23%20attribute%20y_%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20def%20coordinates%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20self.x_,%20self.y_%0A%20%20%20%20%0A%20%20%20%20def%20__str__%28self%29%3A%0A%20%20%20%20%20%20%20%20%22%22%22Cast%20method%20to%20convert%20to%20string%22%22%22%0A%20%20%20%20%20%20%20%20return%20%28f%22Coordinates%20%3A%20%28%20%7Bself.x_%3A25.16e%7D,%20%7Bself.y_%3A25.16e%7D%20%29%22%29%0A%20%20%20%20%20%20%20%20%0A%0Ap1%20%3D%20Point2D%28%29%20%23%20constructs%20a%20point%20with%20default%20internal%20attributes%0Aprint%20%28p1%29%20%23%20Uses%20the%20str%20cast%20method%0A%0Ap2%20%3D%20Point2D%282,%20-3%29%0Aprint%20%28p2%29&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=nevernest&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe>
You can save the class to a file, and then later import it for re-use (you can import any python code)
%%file Point3D.py
class Point3D :
"""This is a doctring. This allows to embed documentation inside the class definition.
You can split it
across several lines.
"""
def __init__(self, x = 0, y = 0, z = 0):
""" This is the constructor"""
self.x_ = x # attribute x_
self.y_ = y # attribute y_
self.z_ = z # attribute z_
def coordinates(self):
return self.x_, self.y_, self.z_
def __str__(self):
"""Cast method to convert to string"""
return (f"Coordinates : ( {self.x_:25.16e}, {self.y_:25.16e}, , {self.z_:25.16e} )")
import Point3D as P3D
p3 = P3D.Point3D(2, 5, 0.9)
print (p3)
Dictionaries#
Dictionaries are the analogous of associative memories or associative arrays. Basically, they are a generalized container where the key is not necessarily an integer but an arbitrary object of inmutable type, called a key (for example, tuples, a reange of number, etc, nut not a list of integers, since the last is mutable).
Dictionaries can be seen as unordered sets of the pairs key:value, and are sourrounded by curly braces {}
. It is posible to delete/acces/add/etc values by using the corresponding key or key/value pair. The keys()
method for a dictionary returns the keys of that dictionary. To check for a given key, you can use the keyword in
.
Refs:
https://realpython.com/python-dicts/
https://quickref.me/python#python-data-types
# creates a dictionary with several key:value pairs. Keys are strings
tel = {'jack': 4098, 'sape': 4139}
print (tel)
# acces by key. If key does not exists, creates a new entry
tel['guido'] = 4127
print (tel)
# Access by key
print (tel['jack'])
# Delete by key
del tel['sape']
print (tel)
# key a list of the keys
print(tel.keys())
# list of values
print(tel.values())
# keys and values
print(tel.items())
%%html
<iframe width="800" height="500" frameborder="0" src="https://pythontutor.com/iframe-embed.html#code=%23%20creates%20a%20dictionary%20with%20several%20key%3Avalue%20pairs.%20Keys%20are%20strings%0Atel%20%3D%20%7B'jack'%3A%204098,%20'sape'%3A%204139%7D%20%20%0Aprint%20%28tel%29%0A%23%20acces%20%20by%20key.%20If%20key%20does%20not%20exists,%20creates%20a%20new%20entry%0Atel%5B'guido'%5D%20%3D%204127%20%0Aprint%20%28tel%29%0A%23%20Access%20by%20key%0Aprint%20%28tel%5B'jack'%5D%29%0A%23%20Delete%20by%20key%0Adel%20tel%5B'sape'%5D%20%20%20%20%0Aprint%20%28tel%29%0A%23%20key%20a%20list%20of%20the%20keys%0Aprint%28tel.keys%28%29%29%20%20%20%0A%23%20list%20of%20values%0Aprint%28tel.values%28%29%29%0A%23%20keys%20and%20values%0Aprint%28tel.items%28%29%29&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=nevernest&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe>
for key, val in tel.items():
print(f"{key=}, {val=}")
'guido' in tel # check if a key is in the dictionary
Exercises#
Some based on “A Primer on Scientific Programming with Python”, Lantangen, Springer
Sorted dictionary#
Write a program which prints a sorted key list of a given dictionary. (hint: Check the sorted
function, or try to sort the keys()
function output)
# YOUR CODE HERE
raise NotImplementedError()
Copying a dictionary#
Search how to copy a dictionary (different to making a reference)
# YOUR CODE HERE
raise NotImplementedError()
Polynomial#
Representing a polynomial by a dictionary : Consider the polynomial \(p(x) = -1 + x^2 + 3x^7\) . It can be represent by means of a dictionary as p = {0:-1, 2:1, 7:3}
(What is the advantage over using a list?). Write a function which gets a dictionary representing a polynomial, an x
value, and returns the polynomial evaluated on that x
value.
# YOUR CODE HERE
raise NotImplementedError()
Histogram#
Make a function which, given a dictionary with values
as ints (a simple version of a histogram), prints the histogram counters as =
. For example (the keys can be arbitrary)
A : ========
B : =============
C : =======
D : ==
E : ==
dict = {'A':8, 'B':12, 'C':5, 'D':2, 'E':2}
# YOUR CODE HERE
raise NotImplementedError()
print_histo(dict)
Histogram of a text#
Make a program which reads a text and counts the numbers of ocurrences for each word.
# YOUR CODE HERE
raise NotImplementedError()
Dictionaries and lists for polynomial#
Modify the previous program for representing a polynomial with a dictionary to represent it with a list. Use both representations for the polynomyal \(-\frac{1}{2} + 2x^{100}\). Print both representations and use both to evaluate that polynomial at \(x = 1.05\) .
# YOUR CODE HERE
raise NotImplementedError()
Polynomial derivative#
By using the dictionary plynomial representation of the previous exercises, write a function which computes the derivative of a given polynomial and returns a dictionary representation of the new polynomial representing the derivative. Test it.
# YOUR CODE HERE
raise NotImplementedError()