Lecture 3

  • Learn about collections of variables: data structures

  • Learn about objects

  • Learn about methods which allow you to do things to objects

Data Structures

Now that we know about variables, it would be handy to group them together in some way. In Python there are many ways to do this: lists, tuples, dictionaries, and sets, among others. These group arbitrary variables together, (e.g., strings and integers and floats) in containers.

We'll go through some of the various data structures, starting with lists.

Lists

  • Lists are denoted with [ ] and can contain any arbitrary set of elements, including other lists!

  • Elements in the list are referenced by an index number (index). Similar to the strings we encountered in the last lecture, the indices begin at 0. Remember that this is different from what you may be used to, which would be that the first element is index 1, whereas in Python, the first element is index 0.

  • You can count from the end to the beginning by starting with -1 (the last item in the list), -2 (second to last), etc.

  • Lists have methods that allow items to be sorted, deleted, inserted, sliced, counted, concatenated, replaced, added on to, etc.

Let's take a look at some examples:

In [14]:
mylist=['a',2.0,'400','spam',42,[24,2]] # defines a list
print (mylist) # prints the list
['a', 2.0, '400', 'spam', 42, [24, 2]]

But if we want to print out the third element in list we use index number 2:

In [15]:
print (mylist[2]) # print the third element in the list (starting from zero)
400
In [16]:
print (mylist[-1]) # print the last element
[24, 2]

But if you want to print, say, the last three elements, you can't do this:

In [17]:
print (mylist[-3:-1])
['spam', 42]

This is because the slice list[begin:end] means from index = begin up to and not including index=end. To actually slice out the last three elements, you can do it this way:

In [18]:
print (mylist[-3:])
['spam', 42, [24, 2]]

Unlike strings, you can change list elements "in place". By "in place" we mean that you don't have to assign it to a new variable name, the list gets change "in place":

In [19]:
mylist[1]=26.3   # replaces the second element
print (mylist)
['a', 26.3, '400', 'spam', 42, [24, 2]]
In [20]:
del mylist[3] # deletes the fourth element 
mylist
Out[20]:
['a', 26.3, '400', 42, [24, 2]]

Like strings, you can slice out a chunk of the middle of a list and assign it to another variable:

In [21]:
newlist=mylist[1:3] # takes the 2nd and third values and puts in newlist
#note it takes out up to but not including the last item number 
print (newlist)
[26.3, '400']

Making copies of lists behaves in ways you might not expect if you are coming from other programming languages. We will learn more about copies of lists in later lectures, but here are some pro tips for now.

You can assign a list to another variable name like this:

In [22]:
mycopy=mylist

mycopy is now a copy of mylist. But it is inextricably bound to the original, so if I change one, I change the other. This type of copy is known as a shallow copy.

In [23]:
mylist[2]='new'
print (mylist)
print (mycopy)
['a', 26.3, 'new', 42, [24, 2]]
['a', 26.3, 'new', 42, [24, 2]]

See how mycopy was changed when we changed mylist?

To spawn a list that is an independent object (a deep copy), you can do this:

In [24]:
mycopy=mylist[:]
# now try changing mylist... 
mylist[2]=1003
print (mycopy) # if there are two things to print, use 'print'
mylist # otherwise only prints the last one
['a', 26.3, 'new', 42, [24, 2]]
Out[24]:
['a', 26.3, 1003, 42, [24, 2]]

See how mycopy stayed the way it was, even as mylist changed?

There are more ways to make shallow and deep copies of Python objects which we will explore further in Lecture 10.

Obects in Python

We have been using the word "object" a lot in this lecture. So what is an object in Python?

An object in Python is a collection that has attributes and methods. The list variable mylist is an example of an object - a list object. In fact they are classes which we will learn more about in Lecture 10.

So what is so special about objects? Python objects have methods which allow you to do things to the object. Methods have the form:

object.method( )

or

object.method(argument1, argument2,...)

Let's look at a few examples starting with the .append( ) method (which appends something to the end of a list).

In [25]:
mylist.append('me too') 
# append() is a method of lists that appends the argument 'me too' to the list
print (mylist)
['a', 26.3, 1003, 42, [24, 2], 'me too']

.count( ) is another method. Let's see what it does:

In [26]:
mylist.append('me too') 
print (mylist.count('me too') )
2

The method .count( ) returns the number of times the argument occurs in the list. [NB: the argument is the stuff inside the parentheses of the method - in this case 'me too'.]

Another very handy list method is the .index( ) method. It returns the index of the desired argument in the list. For example, if we wanted to know what the index of the element, 42, is in mylist, we would type:

In [27]:
print (mylist.index(42) )
3

These are just a few of the methods for lists. To view all of the methods for a list object, see: https://docs.python.org/tutorial/datastructures.html

Making lists

For example, we could make this list:

In [30]:
santas_list=['naughty','nice']
print (santas_list)
# and check it twice
print (santas_list)
['naughty', 'nice']
['naughty', 'nice']

More useful lists:

Earlier, we made a list by defining a variable with square brackets. We added to that list with append( ). Another way to generate a list is to use range( ), which is one of the python built-in functions we mentioned in Lecture 2. range( ) is a list generator and can be used to generate a list of integers between two numbers, the start and end, where each number is separated by a specified interval. Here Python 3 is a bit different from earlier versions of python in that older versions (Python 2.7) generated the list directly, but new to Python 3, you have to make the list from the generator like so: list(range(start,end,interval)). Note that range, like list slicing, goes up to but does not include end.

In [31]:
# creates a list from 2 to 20 (not including 20!) at intervals of 4
numlist=list(range(2,20,4)) 
print (numlist)
[2, 6, 10, 14, 18]

Trying it the "old" way, we just get:

In [32]:
print (range(2,20,4))
range(2, 20, 4)

which is obviously not a list itself.

Tuples

Tuples are another important object in python that are similar to lists, but have important differences. They are denoted by parentheses ( ) and consist of values separated by commas.
Like lists, they can contain different elements, but unlike lists, the elements cannot be changed in place. Their primary use is to pass information into and out of programs as we shall see in the coming lectures.

Similar to both lists and strings, you can slice, concatenate, etc. For more see:

http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences

Here is one way to generate a tuple:

In [33]:
t = 1234, 2.0, 'hello'
print (t)
(1234, 2.0, 'hello')

Or, the other way around:

In [35]:
a,b,c=t
print (a)
print (b)
print (c)
1234
2.0
hello

You can access an element in a tuple by using the index number, exactly like a list.

In [17]:
t[0]
Out[17]:
1234

But, you can't change it:

In [37]:
t[0]='haha'
print (t)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-37-f007a382b75c> in <module>
----> 1 t[0]='haha'
      2 print (t)

TypeError: 'tuple' object does not support item assignment

Sets

There are more data structures that comes in handy and one is the set. They are denoted with curly braces { }. A set "contains an unordered collection of unique and immutable objects."

You can create sets in several ways. The first would be the use the python built-in set( ) function on a list:

In [38]:
S1=set(['spam','ocelot',42])
S1
Out[38]:
{42, 'ocelot', 'spam'}

Notice how the order changed.

Also, notice what happens if we violate the "unique" part of the definition:

In [39]:
S2=set(['spam','ocelot','ocelot'])
S2
Out[39]:
{'ocelot', 'spam'}

Only one of the ocelots made it into the set. [By the way, "ocelot" is another Monty Python joke - look it up if you like.]

Sets contain immutable objects, but they themselves can be changed. For a more complete list of methods see:

https://www.python-course.eu/python3_sets_frozensets.php

But here are a few:

In [40]:
# add
print (S1) 
S1.add('chocolate')
print (S1)
{42, 'ocelot', 'spam'}
{'chocolate', 42, 'ocelot', 'spam'}
In [41]:
# clear 
S2.clear() 
S2
Out[41]:
set()

See how S2 is now just an empty set object set( ).

Now let's try copying S1.

In [42]:
# copy
S2=S1.copy()
print (S2)
S1.clear()
print (S1)
print (S2)
{'chocolate', 42, 'ocelot', 'spam'}
set()
{'chocolate', 42, 'ocelot', 'spam'}

the .copy( ) method for sets does not work like copying lists - it made an independent object S2 which did not clear when S1 got cleared.

.difference is another handy method - it can be used to find what is different about two sets.

In [43]:
# difference
S1=set(['spam','ocelot',42])
S2=set(['spam','ocelot'])
S1.difference(S2)
Out[43]:
{42}

But - you say - you want to know what is the same in two sets. For that, use the .intersection method.

In [44]:
# intersection
S1.intersection(S2)
Out[44]:
{'ocelot', 'spam'}

There is a nice short cut for this:

In [46]:
S1&S2
Out[46]:
{'ocelot', 'spam'}

Finally, you can define a set just using curly braces:

In [45]:
S3={42,'spamalot','Ni'}
S3
Out[45]:
{42, 'Ni', 'spamalot'}

'Ni' is another joke from Monty Python and the Holy Grail where there were some characters calling themselves the "Knights who say Ni!". "42" is not from Monty Python, but from the Hitch Hikers Guid to the Galaxy - but people who like Monty Python also like the Hitch Hiker's Guide. By the way, "42" is the answer to "What is the meaning of life, the universe, and everything?". Now you know.

Assignment #1

  • Create a jupyter notebook.
  • Rename the notebook (under File menu) with the format YourLastname_HW_1. For example, Cych_HW_1
  • Save the notebook (click on the disk icon in the menu bar)
  • Create a markdown block in which you will describe what the notebook does.
  • Make a code block that creates a list called planets
    • append all the planets to the list.
    • make a copy of your planets list (with a different name).
    • print the element at index 2 in your planets list.
    • set the element at index 2 in your copy to 'X'
    • print the element at index 2 in both lists (planets and your copy)
    • append the element that you just changed to the end of your copy.
    • use the help function to find out what the built-in function len() does.
  • Make another code block that creates a list called, e.g., mylist, using range( ) that has 8 values starting with 1.
    • print out your new list
    • Create a set from each of the three lists (planets, your copy of planets and your new list of numbers.
    • Find the elements in common between the two planets lists planets and your copy.
    • find the elements in common between planets and your new numbers list.

Your code must be fully commented.

In [ ]: