from IPython.display import YouTubeVideo
YouTubeVideo("M_eYSuPKP3Y",width="640",height="390")
• Lists: a mutable array of data
• Tuples: ordered, immutable list
• Sets: unordered collection of unique elements
• Dictionaries: keyword/value lookup
The value in each element can be whatever (type) you want.
string is actually a sequence object
denoted with parentheses
t = (12,-1)
print(type(t))
print(isinstance(t,tuple))
print(len(t))
t = (12,"monty",True,-1.23e6)
print(t[1])
print(t[-1])
t[-2:] # get the last two elements, return as a tuple
x = (True) ; print(type(x))
x = (True,) ; print(type(x))
type(()), len(())
type((,))
single-element tuples look like (element,)
cannot change a tuple but you can create new one with concatenation
t[2] = False
type((1,"spam","eggs", None))
t[0:2], False, t[3:]
## the above it
## not what we wanted... need to concatenate
t[0:2] + False + t[3:]
y = t[0:2] + (False,) + t[3:] ; print(y)
t*2
v = [1,2,3] ; print(len(v), type(v))
v[0:2]
v = ["eggs","spam",-1,("monty","python"),[-1.2,-3.5]]
len(v)
v[0] ="green egg"
v[1] += ",love it."
v[-1]
v[-1][1]
v[-1][1] = None ; print(v)
v = v[2:] ; print(v)
# let's make a proto-array out of nested lists
vv = [ [1,2], [3,4] ]
print(len(vv))
determinant = vv[0][0]*vv[1][1] - vv[0][1]*vv[1][0]
print(determinant)
the main point here: lists are changeable ("mutable")
v = [1,2,3]
v.append(4)
print(v)
Lists can be considered objects.
Objects are like animals: they know how to do stuff (like eat and sleep), they know how to interact with others (like make children), and they have characteristics (like height, weight).
"Knowing how to do stuff" with itself is called a method. In this case "append" is a method which, when invoked, is an action that changes the characteristics (the data vector of the list itself).
v = [1,2,3]
v.append(4)
v.append([-5]) ; print(v)
v = v[:4]
w = ['elderberries', 'eggs']
v + w
v.extend(w) ; print(v)
v.pop()
print(v)
v.pop(0) ; print(v) ## pop the first element
v.append(0)
v = ["hello"] + v
print(v)
.append()
: adds a new element.extend()
: concatenates a list/element.pop()
: remove an elementv = [1,3, 2, 3, 4, 1.3]
v.sort() ; print(v)
If there isn't a natural way to compare elements, the sort will fail.
reverse
is a keyword of the .sort()
method
import math
v = [1,3, 2, 3, 4, math.pi]
v.sort() ; print(v)
v.sort(reverse=True) ; print(v)
v.sort?
.sort()
changes the the list in place
v.index(4) ## lookup the index of the entry 4
v.index(3)
v.count(3)
v.insert(0,"it's full of stars") ; print(v)
v.remove(3.0) ; print(v)
Type v.
then the Tab button
Type v.re
then the Tab button
Type v.remove?
## try it here
x = 1
a = ['cat', 'window', 'defenestrate']
for x in a:
print(x, len(x))
if x == "cat":
a.append("?")
print(x)
for i,x in enumerate(a):
print(i, x, len(x))
b = enumerate(a)
print(b.__next__())
for x in a:
print(x, end=',')
The syntax for iteration is...
for variable_name in iterable:
# do something with variable_name
The range()
function
x = list(range(4)) ; print(x)
total = 0
for val in range(4):
total += val
print("By adding " + str(val) + \
" the total is now " + str(total))
range
([start
,] stop
[, step
])
→ list of integers
total = 0
for x in range(1,10,2):
total += x
print("By adding " + str(x) + \
" the total is now " + str(total))
a = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(a)):
print(i, a[i])
{1,2,3,"bingo"}
print(type({1,2,3,"bingo"}))
print(type({}))
print(type(set()))
set(["spamIam"])
sets have unique elements. They can be compared, differenced, unionized, etc.
a = set("sp") ; b = set("am"); print(a) ; print(b)
c = set(["m","a"])
c == b
"p" in a
"ps" in a
q = set("spamIam")
a.issubset(q)
a | b
q - (a | b)
q & (a | b)
Like lists, we can use as (unordered) buckets
.pop()
gives us a random element
# this is pretty volitile...wont be the same
# order on all machines
for i in q & (a | b):
print(i, end=' ')
q.remove("a")
q.pop()
print(q.pop())
print(q.pop())
print(q.pop())
print(q)
q.pop()
denoted with a curly braces and colons
d = {"favorite cat": None, "favorite spam": "all"}
these are key: value, key: value, ...
print(d["favorite cat"])
d[0] ## this is not a list and you dont have a keyword = 0
e = {"favorite cat": None, "favorite spam": "all", \
1: 'loneliest number'}
e[1] == 'loneliest number'
dictionaries are UNORDERED*.
You cannot assume that one key comes before or after another
* you can use a special type of ordered dict if you really need it:
https://docs.python.org/3.1/whatsnew/3.1.html#pep-372-ordered-dictionaries
# number 1...you've seen this
d = {"favorite cat": None, "favorite spam": "all"}
# number 2
d = dict(one = 1, two=2,cat = 'dog') ; print(d)
# number 3 ... just start filling in items/keys
d = {} # empty dictionary
d['cat'] = 'dog'
d['one'] = 1
d['two'] = 2
d
# number 4... start with a list of tuples
mylist = [("cat","dog"), ("one",1),("two",2)]
print(dict(mylist))
dict(mylist) == d
list(d)
d = {"favorite cat": None, "favorite spam": "all"}
d = {'favorites': {'cat': None, 'spam': 'all'}, \
'least favorite': {'cat': 'all', 'spam': None}}
print(d['least favorite']['cat'])
remember: the backslash () allows you to across break lines. Not technically needed when defining a dictionary or list
phone_numbers = {'family': [('mom','642-2322'),('dad','534-2311')],\
'friends': [('Billy','652-2212')]}
for group_type in ['friends','family']:
print("Group",group_type,":",sep=" ")
for info in phone_numbers[group_type]:
print("\t",info[0],info[1],sep=" ")
# this will return a list, but you dont know in what order!
list(phone_numbers.keys())
list(phone_numbers.values())[-1]
.keys()
and .values()
: are called methods
on dictionaries
for group_type in list(phone_numbers.keys()):
print("Group",group_type,":",sep=" ")
for info in phone_numbers[group_type]:
print("\t",info[0],info[1],sep=" ")
we cannot ensure ordering here of the groups
groups = list(phone_numbers.keys())
groups.sort()
for group_type in groups:
print("Group",group_type,":",sep=" ")
for info in phone_numbers[group_type]:
print("\t",info[0],info[1],sep=" ")
.items()
is a handy method,
returning key,value pairs with each iteration
for group_type, vals in phone_numbers.items():
print("Group",group_type,":",sep=" ")
for info in vals:
print("\t",info[0],info[1],sep=" ")
Some examples of getting values:
phone_numbers['co-workers']
'co-workers' in phone_numbers
print(phone_numbers.get('co-workers'))
phone_numbers.get('friends') == phone_numbers['friends']
Defaults in a get
print(phone_numbers.get('co-workers',"all alone"))
phone_numbers.get?
you can edit the values of keys and also .pop()
& del
to remove certain keys
"BFFs" in phone_numbers.keys()
# add to the friends list
phone_numbers['friends'].append(("Marsha","232-1121"))
print(phone_numbers)
## billy's number changed
phone_numbers['friends'][0][1] = "532-1521"
phone_numbers['friends'][0] = ("Billy","532-1521")
## I lost all my friends preparing for this Python class
phone_numbers['friends'] = [] # sets this to an empty list
## remove the friends key altogether
print(phone_numbers.pop('friends'))
print(phone_numbers)
del phone_numbers['family']
print(phone_numbers)
.update()
method is very handy, like .append()
for lists
phone_numbers.update({"friends": [("Billy's Brother, Bob", "532-1521")]})
print(phone_numbers)
a = [1,2,3,("b",1),("b",1)]
b = tuple(a) ; print(b)
print(list(b))
set(a)
list(set("spam"))
casting only affects top-level structure, not the elements
You can create lists "on the fly" by asking simple questions of other iterateable data structures
example: I want a list of all numbers from 0 - 100 whose lowest two bits are both one (e.g., 3, 7, ...) but is not divisible by 11
mylist = []
for num in range(101):
if (num & 2) and (num & 1) and (num % 11 != 0.0):
mylist.append(num)
print(mylist)
mylist=[num for num in range(101) if (num & 2) \
and (num & 1) and (num % 11 != 0.0)]
print(mylist)
example: I want a list of all mesons whose masses are between 100 and 1000 MeV
particles = \
[{"name":"π+" ,"mass": 139.57018}, {"name":"π0" ,"mass": 134.9766},
{"name":"η5" ,"mass": 47.853}, {"name":"η′(958)","mass": 957.78},
{"name":"ηc(1S)", "mass": 2980.5}, {"name": "ηb(1S)","mass": 9388.9},
{"name":"K+", "mass": 493.677}, {"name":"K0" ,"mass": 497.614},
{"name":"K0S" ,"mass": 497.614}, {"name":"K0L" ,"mass": 497.614},
{"name":"D+" ,"mass": 1869.62}, {"name":"D0" ,"mass": 1864.84},
{"name":"D+s" ,"mass": 1968.49}, {"name":"B+" ,"mass": 5279.15},
{"name":"B0" ,"mass": 5279.5}, {"name":"B0s" ,"mass": 5366.3},
{"name":"B+c" ,"mass": 6277}]
# data source: http://en.wikipedia.org/wiki/List_of_mesons
my_mesons = [ (x['name'],x['mass']) for \
x in particles if x['mass'] <= 1000.0 and x['mass'] >= 100.0]
# get the average
tot = 0.0
for x in my_mesons: tot += x[1]
print("The average meson mass in this range is " + str(tot/len(my_mesons)) \
+ " MeV/c^2.")
print("The average meson mass in this range is " + str(round(tot/len(my_mesons),2)) \
+ " MeV/c^2.")
my_mesons[0][0]
bytes(my_mesons[0][0],encoding="utf-8")
Consider the following data (file: airline.py
):
# %load airline.py
airports = {"DCA": "Washington, D.C.", "IAD": "Dulles", "LHR": "London-Heathrow", \
"SVO": "Moscow", "CDA": "Chicago-Midway", "SBA": "Santa Barbara", "LAX": "Los Angeles",\
"JFK": "New York City", "MIA": "Miami", "AUM": "Austin, Minnesota"}
# airline, number, heading to, gate, time (decimal hours)
flights = [("Southwest",145,"DCA",1,6.00),("United",31,"IAD",1,7.1),("United",302,"LHR",5,6.5),\
("Aeroflot",34,"SVO",5,9.00),("Southwest",146,"CDA",1,9.60), ("United",46,"LAX",5,6.5),\
("Southwest",23,"SBA",6,12.5),("United",2,"LAX",10,12.5),("Southwest",59,"LAX",11,14.5),\
("American", 1,"JFK",12,11.3),("USAirways", 8,"MIA",20,13.1),("United",2032,"MIA",21,15.1),\
("SpamAir",1,"AUM",42,14.4)]
Flight Destination Gate Time -------------------------------------------------- Aeroflot 34 Moscow 5 9.0 American 1 New York City 12 11.3 Southwest 23 Santa Barbara 6 12.5 Southwest 59 Los Angeles 11 14.5 ...
hint: you'll need to do a manual sorting on the last element of each flight element, before beginning the printing loop