Lesson 1.4: Tuples, Lists, Dictionaries, Sets
During this lesson, you will learn the following:
Lists
Tuples
Dictionaries
Sets
Lists
A list is a mutable sequence of values.
Flexible arrays, not linked lists
Lists use bracket notation:
[]
Lists are ordered, indexed by integer offset from start
Lists can have mixed types
List Operators
Indexing, slicing, concatenation (+), repetition (*),
len()
all work the sameBut lists are objects and have their own methods...
Documentation for all list methods here: https://docs.python.org/3/tutorial/datastructures.html
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:
-
range(stop)
-- a sequence of values that starts at zero and goes up to (but not including)stop
-
range(start,stop)
-- a sequence of values that starts atstart
and goes up to (but not including)stop
-
range(start,stop,step)
-- a sequence of values that starts atstart
and goes up to (but not including)stop
, incrementing values according tostep
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
The Python language includes a feature called a list comprehension provides a concise way of creating a new list from an existing one
This feature lets you copy a modified version of an existing list (do two things at once):
The generic syntax for performing a list comprehension is (note the use of brackets on the outside so the return is a list):
Note that
x
does not have to be an indexed iterator (e.g. i being used as a typical iterator), rather<list>
is a list object that the enuerator for thefor
loop and there is no index. This is very Pythonic and we'll see many examples.Official documentation available from: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
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 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:
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
Activity - Create a list that calculates for all values from 0 to 9 that are even.
Activity - Create a list that calculates 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:
Activity - Create this list:
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
Lists are a "reference" data type, which are different from the basic types like float, int, string.
A list variable name is a reference that "points to" an address in memory that holds the list items/elements
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:
or
2-Dimensional (Nested) Lists
A two-dimensional (nested) list is a list of references to other lists:
The top-level list contains references to other lists
The lower-level lists contain (ordered) data
You can think of the list referencing as a row-column structure:
list_name[row][column]
Activity
Assign the 3rd row of the "data" variable above, to a variable called "test".
Does it share the same address in memory? Why or why not?
Make two copies of the data variable using different techniques.
Verify that the copy has a different address in memory
Assign a new variable to the data variable.
Change the new variable and verify this changes data.
Higher-Dimensional Lists
The same ideas that apply to 2D lists can be extended for lists of any dimension
These lists can be used to represent data that is a function of more than two independent variables (i.e., values in x, y, z location)
Making Matricies (Nested lists) with list comprehension:
The syntax is fairly straightforward, just nest one list inside of another.
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:
Activity - Create a 2x10 matrix with numerically increasing values:
i.e.
Challenge Activity! - Create a nested pyramid list that looks like this:
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:
To parse a nested list, the syntax changes a little.
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] 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:
But now we add a simple conditional statement.
Parsing a matrix with an if/else conditional
Activity - Create a 5x5 matrix with numerically increasing values:
i.e.
Activity - Create a 3x3 matrix with numerically increasing values:
i.e.
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:
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:
For an if/else statement:
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.
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:
Create any non-square, multi-dimensional list using conditional statements
Parse through the list and create a one dimensional list based on parameters of your choice.
Make a copy of the result
Tuples
A tuple is a sequence of values, separated by commas
support mixed types (e.g., int, float, String, other tuples)
Ordered (indexed)
Immutable
Tuples are typically used by programmers to create "stable" global variables.
It is common (but not required) to enclose tuples in parenthesis (makes it easier to ID tuples in action)
Tuples Are Ordered (Indexed)
Individual elements of a tuple can be accessed using and their index values (an integer)
As with strings, index counting starts with zero.
Slicing for tuples works the same way as it does for Strings.
for
-loops work as with Strings
Other features of tuples
Tuples can store mixed data types
You can store a tuple as an element within a tuple.
You can iterate the elements of a tuple using either
for
loop.
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
The
+
operator concatenates tuplesThe
*
operator repeats tuplesThe
in
operator returns a booleanTrue
if a specified element is presentTuple comparison uses lexicographical order:
Compare the first elements in each tuple, and if they differ this determines the outcome.
If they are equal, then compare the next two elements and so on, until either sequence is exhausted.
If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively.
If all items of two sequences compare equal, the sequences are considered equal.
If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one.
< > ==
operators work element by element
The sorted()
function
Python has a built-in function called
sorted()
that sorts a sequence of values.A new sequence is returned; the original sequence is unchanged
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?
Sometimes called an "associative array", implemented using a hastable
It is best to think of a dictionary as an unordered set of key:value pairs.
The index values are known as a keys.
The data that can be referenced/called with a key is known as the value.
A key-value pair is also known as an item in the dictionary.
Each dictionary requires that its keys are unique.
A pair of braces creates an empty dictionary:
{}
. You can also use thedict()
function.Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.
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
A
for
loop can be used to iterate over dictionary keys, values, or items...In all cases, the order of iteration might vary (could be different on each computer and possibly each time the "same" dictionary is defined).
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
A set behaves like a collection of dictionary keys with no values.
There can be no duplicates in a set (just as for keys in a dictionary).
As Think Python notes, "Adding elements to a set is fast; so is checking membership. And sets provide methods and operators to compute common set operations."
The sets data structure exists so that we can do set operations very fast.
We can accomplish set operations in other ways, but the set data structure is optimized for doing this fast, which is useful for things like confirming someone's security permissions without interupting their workflow, etc..
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
Tuples, Lists, Dictionaries, and Sets are the primary data structures in Python
If you understand how to use these (and use them well), you can do almost anything