nuwc_nps_banner.png

Lesson 1.4: Tuples, Lists, Dictionaries, Sets

During this lesson, you will learn the following:

Lists

List Operators

Another example

The range() function

Python has a built-in function called range() that is often used to quickly create a sequence of values over which to iterate.

range() is an iterator and therefore CANNOT be subdivided decimally. e.g. range(0,10,0.01) -> error

In Python3, the function range() returns an object (a generator) that allows you to iteratively get the next element in the sequence.

There are three ways of creating a range:

As documented here, the advantage of the range type over a regular tuple (or list) is that a range object will always take the same (small) amount of memory, no matter the size of the range it represents (as it only stores the start, stop and step values, calculating individual items and subranges as needed).

The range() function is often combined with the len() function to iterate over the elements of an ordered sequesnce, with the following pattern...

This is a very Matlab way of doing things, but there is another way which is more Pythonic...

List Comprehensions

[ f(x) for x in <list> ]

Activity - Create a list of values from 0 to 9 using list comprehension.

Activity - Create a list of values from 0 to 40 where mod(3)=0.

Activity - Create a list that calculates $x^2$ for all values from 0 to 9.

Activity - Create a list that takes in a list of strings and gives a list with the length of each string.

Challenge Activity! - Create the Fibonacci sequence: 1,1,2,3,5,8,13,...

Fibonacci Sequence as an equation: $int \left( \left[ \left(\frac{1+\sqrt{5}}{2}\right)^n - \left(\frac{1-\sqrt{5}}{2}\right)^n \right]/\sqrt{5} \right)$

Where n are integer values.
Hint: writing the function as a string and then passing it to eval('string') will make this easier.

Now let's take a look at how to use conditions

List comprehension can also accept conditional statements that allow us to create more complicated lists.

Syntax for a simple conditional

[f(x) for x in <list> if <condition>]

Activity - Create a list that calculates $x^2+4x+16$ for all values from 0 to 9 that are even.

Activity - Create a list that calculates $x^2$ for x from 0 to 10 but only keep even values and converts the numbers to strings.

Now let's look at the more comlicated if/else case:

List comprehension also accpets if/else statements but the sytax changes.

Syntax for a complex conditional is a little different:

[f(x) if <condition> else f`(x) for x in list]

Activity - Create this list:

[0,1,-2,3,-4,5,-6,...]

Using list comprehension.

Activity - Create a list from 0 to 15 where every integer that is divisible by 2 or 5 is replaced by a string that says "Divby2or5":.

List Names Are References

When lists are different

When lists are the same

Making sense of copying variables in Python

Many Matlab users will find this behavior to be very annoying, but this is how many other programming languages work.

Python "thinks" of variables like stickers on boxes in a warhouse. If you slap an "x" sticker on a box and then put a "y" sticker on the same box, when you change "x", you will change "y" because both stickers are on the same box.

So how do you copy a variable? There are two ways:

a = b[:] # have we talked about slicing yet?

or

import copy  # We'll talk about this one later

a  = copy.copy(b)

2-Dimensional (Nested) Lists

A two-dimensional (nested) list is a list of references to other lists:

Activity

Higher-Dimensional Lists

Making Matricies (Nested lists) with list comprehension:

The syntax is fairly straightforward, just nest one list inside of another.

[[f(x) for x in <list>] for y in <list>]

Activity - Create a 5x6 matrix of ones:

Activity - Create a 5x3 matrix with values from 5 to 9 on each row:

Activity - Create a 5x5 matrix that follows this pattern:

[[0,1,2...]
[1,2,3...],
[2,3,4...],
 ...
]

Activity - Create a 2x10 matrix with numerically increasing values:

i.e.

[[1,2,3...],[11,12,13...]]

Hint: I used the step size in range to do this.

Challenge Activity! - Create a nested pyramid list that looks like this:

[[],[0],[0,1],[0,1,2],...]

I choose this example to show you that lists do not have to be square like matricies.

Challange Activity - Create Pascal's Triangle.

Using a for loop and list comprehension, write python code to complete the triangle

Challenge Activity! - Create a 5x5 identity matrix, ones along the diagonal and zeros everywhere else:

Hint: I used an if/else statement

So what if you need to parse through a nested list (or matrix)?

We recall that the syntax to create a nested list was:

[[<function> for inner in <list>] for outer in <list>]

To parse a nested list, the syntax changes a little.

[[<lst[outer][inner]> for outer in <list>] for inner in <list>]

Let's try to make some sense of this by simply copying the output of a matrix.

(Note: the code you are about to see is not very Pythonic by calling out lst[y][x] and range(len(lst)). This is very clumsy programming syntax that you don't often see in Python. I am only showing it to you now because it's what you are probably used to seeing. You will see a slicker way of doing this a little later)

Parsing a matrix with a simple conditional

Let's continue using the non-pythonic syntax we used in the nested list example above (i.e. lst[y][x]) and let's add the parsing conditionals from before.

We start with the same syntax as before for parsing a nested list:

[
    [<lst[outer][inner]> for outer in <list>] 
    for inner in <list>
]

But now we add a simple conditional statement.

[
    [<lst[outer][inner]> for outer in <list> if <condition>] 
    for inner in <list>
]

Parsing a matrix with an if/else conditional

[[<lst[outer][inner]> if <condition> else <function> for outer in <list>] for inner in <list>]

Activity - Create a 5x5 matrix with numerically increasing values:

i.e.

[[1,2,3...],[6,7,8...]]

Then parse the matrix and return a 1 if the value is even

Activity - Create a 3x3 matrix with numerically increasing values:

i.e.

[[1,2,3],[4,5,6],[7,8,9]]

Square each value of the matrix.

Then parse the matrix and return "even" if the value is even and "odd" if it is odd

Parsing a multidimentional list to a one dimensional list

Suppose we have a large multi-dimensional matrix and we want to return a list of values that matches our specific criteria.

Traditional programming to do this would look like this:

lst = [[[...],[...]],[[...],[...]],[[...],[...]],[[...],[...]]]

new_lst = []
for 1st_dim in range(len(lst)):
    for 2nd_dim in range(len(lst)):
        for 3rd_dim in range(len(lst)):
            if lst[1st_dim][2nd_dim][3rd_dim] <condition>:
                <function>
            else:
                <function>

Not super pythonic, how would we do this using list comprehension?

In Python, we can simple add for loops onto each other interate through higher dimensions. You can put the new for loops on new lines to make the code easier to read.

For a simple if conditional:

new_lst = [
    <function>  
    for 1st_dim in <list>
    for 2nd_dim in <list>
    for 3rd_dim in <list>
    if <condition> 
]

For an if/else statement:

new_lst = [
    <function> if <condition> else <function> 
    for 1st_dim in <list>
    for 2nd_dim in <list>
    for 3rd_dim in <list>
    ...
]

Parsing non-square lists

Let's make this a little more robust to handle lists that might not be square. The way to do this is to reference the iterator of the previous dimension rather than hard coding in a number. This changes the way the code looks a little.

new_lst = [
    <function>
    for 1st_dim in lst # 1st_dim is each first level list in lst
    for 2nd_dim in 1st_dim # 2nd_dim is each second level list in each 1st level list
    for 3rd_dim in 2nd_dim # 3rd_dim is each thrid level list/element in each 2nd level list
    ...
    if <condition> 
]

Not only with this code handle non-square matricies, it also doesn't rely on writing "fortran" code (e.g. range(len(lst)) which is very long and usually clutters your code with lots of brackets.

Challenge Activity:

Tuples

It is common (but not required) to enclose tuples in parenthesis (makes it easier to ID tuples in action)

Tuples Are Ordered (Indexed)

Other features of tuples

Tuple assignment

You can assign multiple values with tuples...

...which is very useful, especially for swapping values:

Packing/Unpacking Tuples

The following operation is known as "packing" a tuple (we "pack" the values in a tuple container):

The opposite operation is called "unpacking" a tuple:

Sometimes we want to unpack some values together. The * symbol serves as a special operator for tuple unpacking. The * identifies where to put "everything else." Observe the following examples:

Tuple Operators

< > == operators work element by element

The sorted() function

The sorted() function has arguments that you can use to control its behavior: https://docs.python.org/3/library/functions.html#sorted

There is also an official HOW TO tutorial on sorting: https://docs.python.org/3/howto/sorting.html#sortinghowto

Dictionaries

What is a Dictionary?

Complete documentation on dictionaries is available from: https://docs.python.org/3/tutorial/datastructures.html?highlight=dictionary#dictionaries

Two ways to retrieve a value from a dictionary

Adding to a Dictionary: just assign to a new key

Getting/Checking Keys and Values

Iterating/Looping Over a Dictionary

Testing/Searching for Keys

Overwriting / Removing Entries

Dictionaries are objects, and therefore have a host of methods available for use. For documentation on dictionaries: https://docs.python.org/3/tutorial/datastructures.html#dictionaries

Activity - Create a dictionary of Star Wars characters with the associated age and strength. Write a for loop to extract characters whose strength and age are above a threshold.

Sets

Basic Set Manipulation

Set Operations

Let's play around with adding and removing set items

Look what happens when we add 2 to a_set

Note: you cannot slice sets like tuples, lists, or dictionaries.

Sets can also support strings.

We can also use sets on individual characters of a string

Activity - Use sets to test to see if a random integer is prime.

Only check for numbers >50.
primes = 1,2,3,5,7,11,12,17,19,23,29,31,37,41,47

Recap

Next Lesson: 1.5 Functions