<jupyter_start><jupyter_text>Working with Lists - Part 6bThe light and the end of the tunnel - but first, a subtle bug!  Two-Dimensional ListsPython supports two-dimensional lists (list of lists). In this sample, let's make a list of lists for population growth over time.<jupyter_code>population = [
    [106,107,111,133,221,767,1766],
    [502,635,809,947,1402,3634,5268],
    [2,2,2,6,13,30,46],
    [163,203,276,408,547,729,628],
    [2,7,26,82,172,307,392],
    [16,24,38,74,167,511,809]    
]
continents =['Africa','Asia','Australia','Europe','North America','South America']
header = ['Continent','1750','1800','1850','1900','1950','2000','2050']<jupyter_output><empty_output><jupyter_text>We did a quick example last class of building a table with PrettyTable.  **But** I found a subtle bug!<jupyter_code>from prettytable import PrettyTable
pop = population.copy()  #copy the list so we don't change the original list

tab = PrettyTable()
tab.field_names = header

for h in header:
    tab.align[h]='r'

for i in range(len(pop)):
    pop[i].insert(0,continents[i])
    tab.add_row(pop[i])
    
print(tab)<jupyter_output><empty_output><jupyter_text>Everything looks great.  But, look at the value of the population list:<jupyter_code>population<jupyter_output><empty_output><jupyter_text>Drat! That's not supposed to happen!  So, I investigated with a regular list. . .<jupyter_code>numbers = [40,50,60,70,80]
print(numbers)
numbers2 = numbers.copy()
numbers2.extend([90,100,110])
print(numbers2)
print(numbers)<jupyter_output><empty_output><jupyter_text>Everything works - weird!  First, I'm gonna reset population:<jupyter_code>population = [
    [106,107,111,133,221,767,1766],
    [502,635,809,947,1402,3634,5268],
    [2,2,2,6,13,30,46],
    [163,203,276,408,547,729,628],
    [2,7,26,82,172,307,392],
    [16,24,38,74,167,511,809]    
]<jupyter_output><empty_output><jupyter_text>Turns out, I can't copy the whole list at once - I must do it row by row (remember, each row is a list).<jupyter_code>#pop = population.copy()  #copy the list so we don't change the original list

tab = PrettyTable()
tab.field_names = header

for h in header:
    tab.align[h]='r'

for i in range(len(population)):
    temp = population[i].copy()
    temp.insert(0,continents[i])
    tab.add_row(temp)
    
print(tab)<jupyter_output><empty_output><jupyter_text>Now let's see what happens<jupyter_code>population<jupyter_output><empty_output><jupyter_text>Working with DictionariesDictionaries are data structures that have a key/value for every entry.Unlike strings, lists, and tuples, **dictionaries are not sequences** - the data are not stored in order. I found this list of MLB teams. I am going to make a dictionary from it.<jupyter_code>raw = [
    ('Arizona','Diamondbacks'),
    ('Atlanta','Braves'),
    ('Baltimore','Orioles'),
    ('Boston','Red Sox'),
    ('Cincinnati','Reds'),
    ('Cleveland','Indians'),
    ('Colorado','Rockies'),
    ('Detroit','Tigers'),
    ('Houston','Astros'),
    ('Kansas City','Royals'),
    ('Miami','Marlins'),
    ('Milwaukee','Brewers'),
    ('Minnesota','Twins'),
    ('Oakland','Athletics'),
    ('Philadelphia','Phillies'),
    ('Pittsburgh','Pirates'),
    ('San Diego','Padres'),
    ('San Francisco','Giants'),
    ('Seattle','Mariners'),
    ('St. Louis','Cardinals'),
    ('Tampa Bay','Rays'),
    ('Texas','Rangers'),
    ('Toronto','Blue Jays'),
    ('Washington','Nationals'),
    ('Chicago','White Sox'),
    ('Chicago','Cubs'),
    ('Los Angeles','Angels'),
    ('Los Angeles','Dodgers'),
    ('New York','Yankees'),
    ('New York','Mets')]<jupyter_output><empty_output><jupyter_text>Create a simple dictionary from scratch. First, with an empty dictionary.<jupyter_code>teams = dict()
teams['Arizona']='Diamondbacks'
teams['Atlanta']='Braves'
teams
type(teams)<jupyter_output><empty_output><jupyter_text>Create a simple dictionary from scratch with a curly braces and comma-separated list.<jupyter_code>teams2 = {'Arizona': 'Diamondbacks', 'Atlanta': 'Braves',
          'Boston': 'Red Sox'}
teams2<jupyter_output><empty_output><jupyter_text>Create a dictionary from a list of tuples (first value is the key, second value is the value)<jupyter_code>teams3 = dict([
    ('Arizona','Diamondbacks'), ('Atlanta','Braves'),
    ('Baltimore','Orioles'), ('Boston','Red Sox'),
    ('Cincinnati','Reds'), ('Cleveland','Indians'),
    ('Colorado','Rockies'), ('Detroit','Tigers'),
    ('Houston','Astros'), ('Kansas City','Royals'),
    ('Miami','Marlins'), ('Milwaukee','Brewers'),
    ('Minnesota','Twins'), ('Oakland','Athletics'),
    ('Philadelphia','Phillies'), ('Pittsburgh','Pirates'),
    ('San Diego','Padres'), ('San Francisco','Giants'),
    ('Seattle','Mariners'), ('St. Louis','Cardinals'),
    ('Tampa Bay','Rays'), ('Texas','Rangers'),
    ('Toronto','Blue Jays'), ('Washington','Nationals')
    ])
teams3['Chicago']='White Sox'
teams3['Chicago']='Cubs'
teams3
type(teams3)<jupyter_output><empty_output><jupyter_text>Let's flip the entries in the list so we can have non-duplicate keys.<jupyter_code>mlb = dict()
for team in raw:
    key=team[1]
    value=team[0]
    mlb[key]=value    
mlb<jupyter_output><empty_output><jupyter_text>Iterating through the dictionary for unpacking and a for loop<jupyter_code>for name, geo in mlb.items():
    print(f'{geo} hosts the {name}.')<jupyter_output><empty_output><jupyter_text>Using pop() to remove a key/value pair.<jupyter_code>mlb.pop('Tigers')
mlb<jupyter_output><empty_output><jupyter_text>keys() and values()<jupyter_code>for team in mlb.keys():
    print(team)
for team in mlb.values():
    print(team)<jupyter_output><empty_output><jupyter_text>Converting dictionary back to lists - keys(), values(), tuples()<jupyter_code>mlb.keys()
teamnames = list(mlb.keys())
type(teamnames)<jupyter_output><empty_output><jupyter_text>Dictionary comprehensions (have to use .items())<jupyter_code>{team for team, geo in mlb.items()}<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17480288542190908, 'fraction_numerical': 0.046804227478610974, 'mean_word_length': 6.014117647058823, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '528630', 'license': 'CNRI-Python', 'n_tokens_mistral': 2330, 'n_tokens_neox': 2082, 'n_words': 451, 'path': '10.7.20-ClassSession.ipynb', 'repo_name': 'r2klabs/CS150-InClass', 'size': '5961'}