COMP1730/COMP6730 Programming for Scientists
Sequence types, part 2
Announcements
* Mid-semester exam results in 2-3 weeks.
* Homework 4 due next Monday, but can be checked this week if you submitted it yesterday.
* Solving lab exercises is highly recommended!
* Guest lecture tomorrow by A/Prof. Robert Lanfear (Research School of Biology) about how programming helps his research.
Lecture outline
* Lists
* Mutable objects & references
Sequence data types (recap)
* A sequence contains n 0 values (its length), each at an index from 0 to n 1.
* pythons built-in sequence types:
strings (str) contain only characters;
lists (list) can contain a mix of value types; tuples (tuple) are like lists, but immutable.
* Sequence types provided by other modules:
NumPy arrays (numpy.ndarray): fast matrix operations, linear algebra.
Lists
* pythons list is a general sequence type: elements in a list can be values of any type.
* List literals are written in square brackets with comma-separated elements:
>>> alistofints = [2, -4, 2, -8 ] >>> a date = [12, August, 2015] >>> pairs = [ [ 0.4, True ],
[ C, False ] ]
>>> type(pairs)
Creating lists
>>> monday = [18, July]
>>> friday = [22, July]
>>> [monday, friday]
[ [18, July], [22, July] ]
>>> list(abcd)
[a, b, c, d]
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [1/x for x in range(1,6)]
[1.0, 0.5, 0.3333333, 0.25, 0.2]
Lists of lists
>>> A = [ [1, 2], [3, 4, 5],
[6, 7, 8, 9] ]
>>> A[0]
[1, 2]
>>> A[1][2]
5
>>> [1, 2, 3][2]
3
* Indexing and slicing are operators
* Indexing and slicing associate to the left. a list[i][j] == (a list[i])[j].
Lists of lists
>>> A[0]
[1, 2]
>>> A[0:1]
[ [1, 2] ]
>>> A[0:1][1:] []
>>> A[0:1][1]
IndexError: list index out of range
* Indexing a list returns an element, but slicing a list returns a list.
n-dimensional arrays
* NumPy arrays can be n-dimensional.
>>> np.array([ [1,2,3], [4,5,6] ])
array([[1, 2, 3],
[4, 5, 6]])
>>> np.zeros( [2, 3] )
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> np.eye(3)
array([[ 1., 0., 0.]
[ 0., 1., 0.]
[ 0., 0., 1.]])
* Indexing an n-d array returns an (n 1)-d array.
>>> A = np.array([[1,2,3],[4,5,6]])
>>> A[0]
array([1,2,3])
>>> np.transpose(A)[0]
array([1,4])
* Arrays support extended forms of indexing.
>>> A[:,1]
array([2,5])
Lists vs. NumPy arrays
* Lists can contain an arbitrary mix of value types; all values in an array (or a column of a matrix) must be of the same type.
* Arrays support more general forms of indexing (n-dimensional, indexing with an array of integers or Booleans).
* Arrays support element-wise math operations.
* NumPy/SciPy provides many functions on
arrays and matrices (e.g., linear algebra).
* Arrays are more (time and memory) efficient, but this matters only when they are large.
Operations on lists
* list + list concatenates lists:
>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> np.array([1, 2]) + np.array([3, 4])
array([4, 6])
* int * list repeats the list:
>>> 2 * [1, 2]
[1, 2, 1, 2]
>>> 2 * np.array([1, 2])
array([2, 4])
Mutable objects and references
Values are objects
* In python, every value is an object.
* Every object has a unique() identifier.
>>> id(1)
136608064
(Essentially, its location in memory.) * Immutable objects never change.
For example, numbers (int and float), strings and tuples.
* Mutable objects can change.
For example, arrays and lists.
Immutable objects
* Operations on immutable objects create new objects, leaving the original unchanged.
>>> a string = spam
>>> id(a string)
3023147264
>>> b string = a string.replace(p, l) >>> b string
slam
>>> id(b string) 3022616448
>>> a string spam
not the same!
Mutable objects
* A mutable object can be modified yet its identity remains the same.
* Lists and arrays can be modified through: element and slice assignment; and
modifying methods/functions.
* ndarray and list is the only mutable types we have seen so far but there are many other (sets, dictionaries, user-defined classes).
Element & slice assignment
>>> alist = [1, 2, 3] >>> id(a list) 3022622348
>>> b list = a list >>> a list[2] = 0
>>> b list
[1, 2, 0]
>>> b list[0:2] = [A, B] >>> a list
[A, B, 0]
>>> id(b list)
3022622348
the same object!
Modifying list methods
* a list.append(new element)
* a list.insert(index, new element) * a list.pop(index)
index defaults to -1 (last element).
* a list.insert(index, new element) * a list.extend(an iterable)
* a list.sort()
* a list.reverse()
* Note: Most do not return a value.
Lists contain references
* Assignment associates a (variable) name with a reference to a value (object).
The variable still references the same object (unless reassigned) even if the object is modified.
* A list contains references to its elements.
* Slicing a list creates a new list, but containing
references to the same objects (shallow copy). * Slice assignment does not copy.
>>> a list = [1,2,3] >>> b list = a list >>> a list.append(4) >>> print(b list)
>>> a list = [1,2,3] >>> b list = a list[:] >>> a list.append(4) >>> print(b list)
Image from pythontutor.com
Image from pythontutor.com
>>> a list = [ [1,2], [3,4] ] >>> b list = a list[:]
>>> a list[0].reverse()
>>> b list.reverse()
>>> print(b list)
Image from pythontutor.com
>>> a list = [ [1,2], [3,4] ] >>> b list = a list[:]
>>> a list[0] = a list[0][::-1] >>> b list.reverse()
>>> print(b list)
Image from pythontutor.com
>>> a list = [1,2,3]
>>> b list = [4,5,6]
>>> a list.append(b list) >>> c list = a list[:] >>> b list[0] = A
Image from pythontutor.com
Common mistakes
>>> a list = [3,1,2]
>>> a list = a list.sort()
>>> a list = [1,2,3]
>>> b list = a list
>>> a list.append(b list)
>>> a list = [[]] * 3 >>> a list[0].append(1)
NumPy arrays
* Slicing arrays does not (even shallow) copy:
>>> x = np.arange(1,6)
>>> y = x[1:-1]
>>> y
array([2, 3, 4])
>>> x[0:3] = np.zeros(3)
>>> y
array([0, 0, 4])
* The slice acts like a window into the array.
* Indexing with an array does copy.
Reviews
There are no reviews yet.