Introduction to Python
davidbpython.com
Project Warmup Exercise Solutions, Session 6
Ex. 6.1 | Given the below two structures, print the values 'c' (from the list) and 2 (from the dict) |
mylist = ['a', 'b', 'c', 'd'] mydict = {'a': 1, 'b': 2, 'c': 3} |
|
Suggested Solution:
print(mylist[2]) print(mydict['b']) |
|
Ex. 6.2 | Given the below list, loop through and print each item. |
Suggested Solution:
mylist = ['a', 'b', 'c', 'd'] for item in mylist: print(item) |
|
Ex. 6.3 | Given the below dict, loop through and print each key/value pair |
Suggested Solution:
mydict = {'a': 1, 'b': 2, 'c': 3} for key in mydict: print(key, mydict[key]) |
|
Ex. 6.4 | Print the values 'd', 1, 'gamma' and 'Thing'. |
Suggested Solution:
mylist = [
[ 'a', 'b', 'c', 'd' ],
[ 1, 2, 3, 4 ],
[ 'alpha', 'beta', 'gamma', 'delta' ],
[ 'Torchy', 'Thing', 'Girl', 'Fantastic' ]
]
print(mylist[0][3])
print(mylist[1][0])
print(mylist[2][2])
print(mylist[3][1])
|
|
Ex. 6.5 | Loop through and print each row (i.e., each list) as a whole. |
Suggested Solution:
mylist = [
[ 'a', 'b', 'c', 'd' ],
[ 1, 2, 3, 4 ],
[ 'alpha', 'beta', 'gamma', 'delta' ],
[ 'Torchy', 'Thing', 'Girl', 'Fantastic' ]
]
for this_list in mylist:
print(this_list)
|
|
This exercise encourages us to work with a multidimensional structure in a very basic way. A list of lists is just that - if we loop through the items in mylist, then each item in mylist will be a list. Just printing each item gives us a print of each list as a whole (i.e., without looping through the items in each of the "inner" lists. |
|
Ex. 6.6 | Loop through mylist and print only the 2nd element of each list. |
Suggested Solution:
mylist = [
[ 'a', 'b', 'c', 'd' ],
[ 1, 2, 3, 4 ],
[ 'alpha', 'beta', 'gamma', 'delta' ],
[ 'Torchy', 'Thing', 'Girl', 'Fantastic' ]
]
for this_list in mylist:
print(this_list[1])
|
|
Taking it a step further, we see how access to each "inner" list means that we can access any of the elements of the "inner" list. So if we think of a list of lists as a list of rows, we can do things like print a single column, just by printing the same element of each list. |
|
Ex. 6.7 | Print out the word 'beta' from mylist in one simple statement (do not use a loop). |
Suggested Solution:
mylist = [
[ 'a', 'b', 'c', 'd' ],
[ 1, 2, 3, 4 ],
[ 'alpha', 'beta', 'gamma', 'delta' ],
[ 'Torchy', 'Thing', 'Girl', 'Fantastic' ]
]
print(mylist[2][1])
|
|
Since each list is addressible by subscript, we can also pinpoint a single element in the structure by targeting the index "address" of each element. The way to think about this is first to identify the location of the "inner" structure where the targeted element is (in this case, the 3rd "inner" list). You could even print this "inner" structure as a whole, i.e. print mylist[2]. This shows you that the list with the element you want is indeed at that location. You can then think of that "inner" list as accessible through mylist[2] and work with it in the same way you would a named structure (i.e., assigned to a name like mylist). It is then a simple matter to access the targeted element within the "inner" structure by again using a subscript -- in this case, "beta" is in the 3rd element (index 2) within the "inner" structure. You can treat mylist[2] as the list itself (because we access it through an index rather than through a name) and simply subscript this inner list in the same way you would a named structure -- mylist[2][1]. |
|
Ex. 6.8 | Loop through the list of dicts, printing each one on a separate line. |
Suggested Solution:
lod = [
{
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
{
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
{
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
},
]
for this_dict in lod:
print(this_dict)
|
|
Same as an earlier exercise: if the list contains dicts, you can print each dict by looping through the list and printing each dict. This will lead us into accessing individual elements, etc. Note that each dict in the supplied list has the same keys. This list of dicts is meant to represent rows in a table -- the key names indicate the column names from the table. |
|
Ex. 6.9 | Loop through the list of dicts, printing just the company name from each dict. |
Suggested Solution:
lod = [
{
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
{
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
{
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
},
]
for this_dict in lod:
print(this_dict['name'])
|
|
This exercise is analogous to printing a particular element in each of a list of lists. It can also be considered as the printing of each value in a column of the table from which this structure was derived. Here we are printing the 'name' column values. |
|
Ex. 6.10 | Loop through the list of dicts, printing the info in a formatted form. (I've added an extra blank print statement to separate records.) |
Suggested Solution:
lod = [
{
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
{
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
{
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
},
]
for this_dict in lod:
print(this_dict['name'])
print(f"{this_dict['city']}, {this_dict['state']}")
print()
|
|
Now we're putting the values in each dict to use -- as you loop through each item in the list, you have access to each "row" of data (that originally came from a table) in a very convenient form - to get the 'name' for that row, use the 'name' key, for 'city' for that row use the 'city' key, etc. We are only printing the values in a different form, but we can of course do other things with the data -- sum up a column, create a set of cities, etc. |
|
Ex. 6.11 | Loop through the pages for whateva.com |
Suggested Solution:
sites_pages = {
'example.com': [
'index.html',
'about_us.html',
'contact_us.html'
],
'something.com': [
'index2.html',
'prizes.html',
'puppies.html',
],
'whateva.com': [
'main.html',
'getting.html',
'setting.html',
],
}
for page in sites_pages['whateva.com']:
print(page)
|
|
Looping through an "inner" list -- this simply reinforces the idea that an "inner" or "anonymous" structure can be accessed through the "outer" structure. Since the key for 'whateva.com' is associated with a list, you can access this list through sites_pages['whateva.com'], and thus anything that can be done with a named list can be done through the outer dict at this key. Notice the syntax for the solution is no different from an ordinary list looping, except that instead of the list name we use the location of the list in the outer dict -- site_pages['whateva.com']. |
|
Ex. 6.12 | In one statement and without looping, print just the name puppies.html |
Suggested Solution:
sites_pages = {
'example.com': [
'index.html',
'about_us.html',
'contact_us.html'
],
'something.com': [
'index2.html',
'prizes.html',
'puppies.html',
],
'whateva.com': [
'main.html',
'getting.html',
'setting.html',
],
}
print(sites_pages['something.com'][2])
|
|
Again, this is "inner" element access as described in the earlier exercise. |
|
Ex. 6.13 | Loop through the entire sites_pages dict of lists, and print each site and page. Use spaces and empty print statements to enhance formatting. |
Suggested Solution:
sites_pages = {
'example.com': [
'index.html',
'about_us.html',
'contact_us.html'
],
'something.com': [
'index2.html',
'prizes.html',
'puppies.html',
],
'whateva.com': [
'main.html',
'getting.html',
'setting.html',
],
}
for sitename in sites_pages:
print(sitename)
for page in sites_pages[sitename]:
print(' ' + page)
print()
|
|
Finally we use a nested for loop (i.e., a for loop inside a for loop) to get through an entire structure (as you will do in the homework). You can begin a process like this by simply looping through the outer structure (as we did at the start of this section of exercises). This is a dict, so we can simply print the key and value in the dict, which will render for us a string key and a list value. Once this is established and understood, and we can see that each "inner" list is accessed through sites_pages[sitename] (where sitename is the current key in ths looping), we can then loop through the inner list by simply looping through site_pages[sitename]. However, we must remember that we are addressing each key/value pair one at a time, so the loop through the "inner" list must be done inside the loop of the "outer" dict's keys. |
|
Ex. 6.14 | Print the name 'Apex Pharma' |
dod = {
'a': {
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
'b': {
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
'c': {
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
}
}
print(dod['a']['name'])
|
|
Ex. 6.15 | Print the state 'NY' |
dod = {
'a': {
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
'b': {
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
'c': {
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
}
}
print(dod['b']['state'])
|
|
Ex. 6.16 | Loop through and print each key/value pair in the dict |
dod = {
'a': {
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
'b': {
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
'c': {
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
}
}
for key in dod:
print(key, dod[key])
|
|
Ex. 6.17 | Building on the previous solution, print out each key and then the company name associated with that key. |
dod = {
'a': {
'name': 'Apex Pharma',
'city': 'Louisville',
'state': 'KY',
},
'b': {
'name': 'Beta IT',
'city': 'New York',
'state': 'NY',
},
'c': {
'name': 'Gamma Husbandry',
'city': 'Lancaster',
'state': 'PA',
}
}
for key in dod:
print(key, dod[key]['name'])
|
|
READING FROM .json FILE |
|
Ex. 6.18 | Open the config.json file and load into a Python data structure. Print the type of the resulting object. |
Suggested Solution:
import json
fh = open('../config.json')
obj = json.load(fh)
fh.close()
|
|
BUILDING MULTIDIMENSIONAL STRUCTURES |
|
Ex. 6.19 | Build a list of ids: inside a loop through student_db_names.txt, split the line and append each id to outer_list. After the loop ends, print the list. Then print the first element in the list. |
outer_list = []
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
outer_list.append(id)
print(outer_list)
print()
print(outer_list[0])
fh.close()
|
|
A simple list append of strings builds this structure. Compare this to the next solution. |
|
Ex. 6.20 | Build a list of lists: continuing from the above solution, inside the loop create an "inner list" of just the id, city and state, and instead of appending the id, append this 3-element list to outer_list. After the loop ends, pretty-print the resulting list of lists (i.e. print(json.dumps(outer_list, indent=4)). Element access: access the city of the first row (i.e., the 2nd element of 1st list) using a double subscript. |
import json
outer_list = []
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
inner_list = [id, city, state]
outer_list.append(inner_list)
print((json.dumps(outer_list, indent=4)))
print()
print(outer_list[0][1])
fh.close()
|
|
This list append is the same as the simple list append, but this time we are appending a list instead of a string. So instead of appending a single field as an item we're appending multiple fields -- this is the essence of a multidimensional container. |
|
Ex. 6.21 | Build a list of dicts: modifying the above solution, instead of an inner list, inside the loop create an "inner dict" of the id, city and state, keyed to strings 'id', 'city', and 'state'. |
import json
outer_list = []
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
inner_dict = { 'id': id, 'city': city, 'state': state }
outer_list.append(inner_dict)
print((json.dumps(outer_list, indent=4)))
print()
print(outer_list[3]['city'])
fh.close()
|
|
Again, we append a container of values instead of a single value. The only difference here is that the inner structure is a dict instead of a list. |
|
Ex. 6.22 | Build a dict of ids paired to states: inside the loop, add a key/value pair to outer_dict: the id paired with the state. Once the loop is done, print the dict. Then print the value for key ak9. |
import json
outer_dict = {}
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
outer_dict[id] = state
print((json.dumps(outer_dict)))
print()
print(outer_dict['ak9'])
fh.close()
|
|
Now working with an outer dict instead of an outer list, we begin by reviewing the simple add of key/value pair to a dict -- in this case the student id paired with the student's state. |
|
Ex. 6.23 | Build a dict of dicts: inside the loop, create an "inner dict" of street, city, state and zip. Then, still inside the loop, add a key/value pair to outer_dict: the id paired with the inner_dict. |
import json
outer_dict = {}
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
inner_dict = {'street': street, 'city': city,
'state': state, 'zip': zip }
outer_dict[id] = inner_dict
print((json.dumps(outer_dict, indent=4)))
print()
print(outer_dict['ak9']['state'])
fh.close()
|
|
Continuing the same progression as with the list, here we are pairing the student id with the entire row of data for the id, in the form of a convenient dict. So as we did with the list of dicts, inside the loop we simply create a new "inner" dict out of the row data that we want to include, and then pair the student id with this "inner" dict. |
|
Ex. 6.24 | Build a "counting" dictionary, a dict of ints: as a review, create a counting dictionary that counts the number of occurrences of each state. |
outer_dict = {}
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
if state not in outer_dict:
outer_dict[state] = 0
outer_dict[state] = outer_dict[state] + 1
print(outer_dict)
print(); print(outer_dict['NY'])
fh.close()
|
|
Now stepping back again, we review the "counting" dictionary we employed in the unit on dictionaries. As we did then, we are looping through data that contains repeating keys (the id). We must consider whether or not the id key is new to the dictionary, and if it is, we need to set an initial key/value pair in the dict -- setting the value for this key to 0. Then, whether or not the key is new, we can increment the value -- so if the key is new, the value will be 1; and if it is not new, it will be incremented from its previous value. (We're returning to the counting dictionary in order to prepare to do something very similar with a dict of lists - an aggregation of values associated with a state.) |
|
Ex. 6.25 | Build a dict of lists (states): modify the above solution so that each state is associated with a list of ids for that state. |
import json
outer_dict = {}
fh = open('../student_db_names.txt')
lines = fh.readlines()[1:]
for line in lines:
id, fname, lname, street, city, state, zip = line.split(':')
if state not in outer_dict:
outer_dict[state] = []
outer_dict[state].append(id)
print((json.dumps(outer_dict, indent=4)))
print()
for id in outer_dict['NJ']:
print(id)
fh.close()
|
|
Note well the extreme similarity between the "check and add" code in this solution, and the one used in a standard counting dictionary. In the counting dict, we're setting the value to 0 if the key is new, and then incrementing the value. In this dict of lists, we're setting the value to [] (empty list) if the key is new, and then appending the current id value to the list. So we've simply replaced the integer counter that can be incremented with a list that can be appended to. The point of this program is to be able to aggregate students to their home states. We might do this if we wanted to send a mailer to all the students from New York, for example. |
|
Ex. 6.26 | Using the file "revenue.csv", build a "summing" dictionary, a dict of floats. |
outer_dict = {}
fh = open('../revenue.csv')
for line in fh:
company, state, revenue = line.split(',')
if state not in outer_dict:
outer_dict[state] = 0.0
outer_dict[state] = outer_dict[state] + float(revenue)
print(outer_dict)
print()
print(outer_dict['NJ'])
fh.close()
|
|
Again returning to a review, we see the standard "summing" dictionary that we used in the unit on dicts. Of course this is extremely similar to the counting dictionary, but instead of using an int that is incremented, we are using a float that is summed with other floats that are on the same line as the state key. |
|
Ex. 6.27 | Build a dict of lists (floats): modify the above solution so that each state is associated with a list of revenue floats for that state. |
import json
outer_dict = {}
fh = open('../revenue.csv')
for line in fh:
company, state, revenue = line.split(',')
if state not in outer_dict:
outer_dict[state] = []
outer_dict[state].append(float(revenue))
print((json.dumps(outer_dict, indent=4)))
print()
print(sum(outer_dict['NY']) / len(outer_dict['NY']))
fh.close()
|
|
Again, please note the similarity between this solution and the float sum solution. If the state key is new, insteading of setting a new pair in which the value is a float, we are setting a new key/value pair in which the value is an empty list. Then instead of adding each new float to the running float sum, we're appending each new float to a list. Send me questions! |
|