These notes follow the official python tutorial pretty closely: http://docs.python.org/3/tutorial/
In [ ]:
from __future__ import print_function
Lists group together data. Many languages have arrays (we'll look at those in a bit in python). But unlike arrays in most languages, lists can hold data of all different types -- they don't need to be homogeneos. The data can be a mix of integers, floating point or complex #s, strings, or other objects (including other lists).
A list is defined using square brackets:
In [10]:
a = [1, 2.0, "my list", 4]
In [11]:
print(a)
We can index a list to get a single element -- remember that python starts counting at 0:
In [12]:
print(a[2])
Like with strings, mathematical operators are defined on lists:
In [13]:
print(a*2)
The len()
function returns the length of a list
In [14]:
print(len(a))
Unlike strings, lists are mutable -- you can change elements in a list easily
In [15]:
a[1] = -2.0
a
Out[15]:
In [16]:
a[0:1] = [-1, -2.1] # this will put two items in the spot where 1 existed before
a
Out[16]:
Note that lists can even contain other lists:
In [17]:
a[1] = ["other list", 3]
a
Out[17]:
Just like everything else in python, a list is an object that is the instance of a class. Classes have methods (functions) that know how to operate on an object of that class.
There are lots of methods that work on lists. Two of the most useful are append, to add to the end of a list, and pop, to remove the last element:
In [18]:
a.append(6)
a
Out[18]:
In [19]:
a.pop()
Out[19]:
In [20]:
a
Out[20]:
An operation we'll see a lot is to begin with an empty list and add elements to it. An empty list is created as:
a = []
In [24]:
a = []
a.append(1)
a.append(2)
a.append(3)
a.append(4)
a.append(5)
a
Out[24]:
In [25]:
a.pop()
Out[25]:
In [26]:
a.pop()
Out[26]:
In [27]:
a.pop()
Out[27]:
In [28]:
a.pop()
Out[28]:
In [29]:
a.pop()
Out[29]:
In [30]:
a.pop()
In [ ]:
copying may seem a little counterintuitive at first. The best way to think about this is that your list lives in memory somewhere and when you do
a = [1, 2, 3, 4]
then the variable a
is set to point to that location in memory, so it refers to the list.
If we then do
b = a
then b
will also point to that same location in memory -- the exact same list object.
Since these are both pointing to the same location in memory, if we change the list through a
, the change is reflected in b
as well:
In [ ]:
a = [1, 2, 3, 4]
b = a # both a and b refer to the same list object in memory
print(a)
a[0] = "changed"
print(b)
if you want to create a new object in memory that is a copy of another, then you can either index the list, using :
to get all the elements, or use the list()
function:
In [ ]:
c = list(a) # you can also do c = a[:], which basically slices the entire list
a[1] = "two"
print(a)
print(c)
Things get a little complicated when a list contains another mutable object, like another list. Then the copy we looked at above is only a shallow copy. Look at this example—the list within the list here is still the same object in memory for our two copies:
In [ ]:
f = [1, [2, 3], 4]
print(f)
In [ ]:
g = list(f)
print(g)
Now we are going to change an element of that list [2, 3]
inside of our main list. We need to index f
once to get that list, and then a second time to index that list:
In [ ]:
f[1][0] = "a"
print(f)
print(g)
Note that the change occured in both—since that inner list is shared in memory between the two. Note that we can still change one of the other values without it being reflected in the other list—this was made distinct by our shallow copy:
In [ ]:
f[0] = -1
print(g)
print(f)
Note: this is what is referred to as a shallow copy. If the original list had any special objects in it (like another list), then the new copy and the old copy will still point to that same object. There is a deep copy method when you really want everything to be unique in memory.
When in doubt, use the id()
function to figure out where in memory an object lies (you shouldn't worry about the what value of the numbers you get from id
mean, but just whether they are the same as those for another object)
In [ ]:
print(id(a), id(b), id(c))
There are lots of other methods that work on lists (remember, ask for help)
In [ ]:
my_list = [10, -1, 5, 24, 2, 9]
my_list.sort()
print(my_list)
In [ ]:
print(my_list.count(-1))
my_list
In [ ]:
help(a.insert)
In [ ]:
a.insert(3, "my inserted element")
In [ ]:
a
joining two lists is simple. Like with strings, the +
operator concatenates:
In [ ]:
b = [1, 2, 3]
c = [4, 5, 6]
d = b + c
print(d)
A dictionary stores data as a key:value pair. Unlike a list where you have a particular order, the keys in a dictionary allow you to access information anywhere easily:
In [ ]:
my_dict = {"key1":1, "key2":2, "key3":3}
In [ ]:
print(my_dict["key1"])
you can add a new key:pair easily, and it can be of any type
In [ ]:
my_dict["newkey"] = "new"
print(my_dict)
Note that a dictionary is unordered.
You can also easily get the list of keys that are defined in a dictionary
In [ ]:
keys = list(my_dict.keys())
print(keys)
and check easily whether a key exists in the dictionary using the in
operator
In [ ]:
print("key1" in keys)
print("invalidKey" in keys)
list comprehensions provide a compact way to initialize lists. Some examples from the tutorial
In [ ]:
squares = [x**2 for x in range(10)]
In [ ]:
squares
here we use another python type, the tuple, to combine numbers from two lists into a pair
In [ ]:
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
Use a list comprehension to create a new list from squares
containing only the even numbers. It might be helpful to use the modulus operator, %
In [ ]:
tuples are immutable -- they cannot be changed, but they are useful for organizing data in some situations. We use () to indicate a tuple:
In [ ]:
a = (1, 2, 3, 4)
In [ ]:
print(a)
We can unpack a tuple:
In [ ]:
w, x, y, z = a
In [ ]:
print(w)
In [ ]:
print(w, x, y, z)
Since a tuple is immutable, we cannot change an element:
In [ ]:
a[0] = 2
But we can turn it into a list, and then we can change it
In [ ]:
z = list(a)
In [ ]:
z[0] = "new"
In [ ]:
print(z)
To write a program, we need the ability to iterate and take action based on the values of a variable. This includes if-tests and loops.
Python uses whitespace to denote a block of code.
In [ ]:
n = 0
while n < 10:
print(n)
n += 1
This was a very simple example. But often we'll use the range()
function in this situation. Note that range()
can take a stride.
In [ ]:
for n in range(2, 10, 2):
print(n)
In [ ]:
print(list(range(10)))
if
allows for branching. python does not have a select/case statement like some other languages, but if
, elif
, and else
can reproduce any branching functionality you might need.
In [ ]:
x = 0
if x < 0:
print("negative")
elif x == 0:
print("zero")
else:
print("positive")
it's easy to loop over items in a list or any iterable object. The in
operator is the key here.
In [ ]:
alist = [1, 2.0, "three", 4]
for a in alist:
print(a)
In [ ]:
for c in "this is a string":
print(c)
We can combine loops and if-tests to do more complex logic, like break out of the loop when you find what you're looking for
In [ ]:
n = 0
for a in alist:
if a == "three":
break
else:
n += 1
print(n)
(for that example, however, there is a simpler way)
In [ ]:
print(alist.index("three"))
for dictionaries, you can also loop over the elements
In [ ]:
my_dict = {"key1":1, "key2":2, "key3":3}
for k, v in my_dict.items():
print("key = {}, value = {}".format(k, v)) # notice how we do the formatting here
In [ ]:
for k in sorted(my_dict):
print(k, my_dict[k])
sometimes we want to loop over a list element and know its index -- enumerate()
helps here:
In [ ]:
for n, a in enumerate(alist):
print(n, a)
zip()
allows us to loop over two iterables at the same time. Consider the following two
lists:
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = ["a", "b", "c", "d", "e", "f", "g", "h"]
zip(a, b)
will act like a list with each element a tuple with one item from a
and the corresponding element from b
.
Try looping over these lists together (using zip()
) and print the corresponding elements from each list together on a single line.
In [ ]:
The .split()
function on a string can split it into words (separating on spaces).
Using .split()
, loop over the words in the string
a = "The quick brown fox jumped over the lazy dog"
and print one word per line
In [ ]: