Python Programming · Week 9

Dictionaries and Sets

Hyeongmin Lee · SeoulTech, Dept. of Electronic Engineering

This week

Find it by name

names = ["Kim", "Lee", "Park", "Choi"]

scores = [85, 72, 93, 60]

index 0123 names "Kim""Lee""Park""Choi" scores 85729360

Park's score?

for i in range(len(names)):

if names[i] == "Park":

print(scores[i])

93

two lists, matched by position · both must keep the same order

This week

Find it by key

names = ["Kim", "Lee", "Park", "Choi"]

scores = [85, 72, 93, 60]

book = dict(zip(names, scores))

for name, score in book.items():

print(f"{name}: {score}")

print(f"Average: {sum(book.values()) / len(book)}")

while True:

name = input("Name: ")

if name == "":

break

print(book.get(name, "not found"))

←two lists → one dictionary

←key and value, one pair per iteration

←all the values

←a value by its key, or a default

Kim: 85

Lee: 72

Park: 93

Choi: 60

Average: 77.5

Name: Park

93

Name: Kang

not found

Name:

a dictionary: find a value by its key · no positions to match

Dictionaries

A dictionary

>>>book = {"Kim": 85, "Lee": 72, "Park": 93}

>>>book

{'Kim': 85, 'Lee': 72, 'Park': 93}

>>>len(book)

33 pairs

>>>{}

{}an empty dictionary

key value "Kim"→85"Lee"→72"Park"→93
{ }curly braces key: valuea pair ,between pairs

a dictionary: key-value pairs · each key leads to its value

Dictionaries

Find a value by its key

a dictionary · by key

>>>book = {"Kim": 85, "Lee": 72, "Park": 93}

>>>book["Park"]

93

>>>book["Kang"]

KeyError: 'Kang'

"Kim"→85"Lee"→72"Park"→93

a list · week 7 · by position

>>>scores = [85, 72, 93, 60]

>>>scores[2]

93

index 0123 85729360
[key] gives its value a missing key: KeyError
Dictionaries

Add and change

>>>book = {}

{}

an empty dictionary

>>>book["Kim"] = 85

"Kim"85

a new key: added

>>>book["Lee"] = 72

"Kim"85"Lee"72

added at the end

>>>book["Kim"] = 90

"Kim"90"Lee"72

a key already there: changed

>>>{"Kim": 85, "Kim": 90}

{'Kim': 90}one key, one value

a key appears only once · the last value stays

Dictionaries

Is the key there?

>>>book = {"Kim": 85, "Lee": 72, "Park": 93}

>>>"Park" in book

True

>>>"Kang" in book

False

>>>85 in book

False

in looks at the keys

book[key] book.get(key) book.get(key, 0) "Park"there 93 93 93 "Kang"missing KeyError: 'Kang' Noneno error 0default

in: is the key there? · get: no KeyError, None or a default

Loops

for over a dictionary

book = {"Kim": 85, "Lee": 72, "Park": 93}

book → "Kim""Lee""Park" the keys, in order

for name in book:name = "Kim"name = "Lee"name = "Park"

print(f"{name}: {book[name]}")

Kim: 85

Lee: 72

Park: 93

no more keys: the loop ends

for over a dictionary takes the keys · book[name]: its value

Loops

keys() and values()

book = {"Kim": 85, "Lee": 72, "Park": 93}

for name in book.keys():

print(name)

Kim

Lee

Park

the same as for name in book:

for score in book.values():

print(score)

85

72

93

only the values

>>>sum(book.values())

250

>>>max(book.values())

93

keys(): only the keys · values(): only the values

Loops

items(): key and value

book = {"Kim": 85, "Lee": 72, "Park": 93}

book.items() → ('Kim', 85)('Lee', 72)('Park', 93) (key, value) tuples

for name, score in book.items():name, score = ('Kim', 85)name, score = ('Lee', 72)name, score = ('Park', 93)

print(f"{name}: {score}")

Kim: 85

Lee: 72

Park: 93

items(): each key with its value · unpacked in the for line

Loops

zip: two lists side by side

names = ["Kim", "Lee", "Park", "Choi"]

scores = [85, 72, 93, 60]

names "Kim""Lee""Park""Choi" scores 85729360
zip(names, scores) → ('Kim', 85)('Lee', 72)('Park', 93)('Choi', 60)

for name, score in zip(names, scores):name, score = ('Kim', 85)name, score = ('Lee', 72)name, score = ('Park', 93)name, score = ('Choi', 60)

print(f"{name}: {score}")

Kim: 85

Lee: 72

Park: 93

Choi: 60

zip pairs the items at the same position · one pair per iteration

Dictionaries

Two lists into a dictionary

>>>names = ["Kim", "Lee", "Park", "Choi"]

>>>scores = [85, 72, 93, 60]

>>>dict(zip(names, scores))

{'Kim': 85, 'Lee': 72, 'Park': 93, 'Choi': 60}

('Kim', 85)

('Lee', 72)

('Park', 93)

('Choi', 60)

key value "Kim"→85"Lee"→72"Park"→93"Choi"→60

each pair becomes a key and its value · dict(zip(keys, values))

Counting

Counting with a dictionary

counts = {}

for ch in "banana":

if ch in counts:

counts[ch] += 1

else:

counts[ch] = 1

print(counts)

{'b': 1, 'a': 3, 'n': 2}

>>>"banana".count("a")

3one letter at a time

chcounts, after this iteration
{}before the loop
"b" {'b': 1} first time: 1
"a" {'b': 1, 'a': 1} first time: 1
"n" {'b': 1, 'a': 1, 'n': 1} first time: 1
"a" {'b': 1, 'a': 2, 'n': 1} one more
"n" {'b': 1, 'a': 2, 'n': 2} one more
"a" {'b': 1, 'a': 3, 'n': 2} one more

the first time: 1 · after that: one more

Counting

The first time: KeyError

counts = {}

for ch in "banana":

counts[ch] += 1

KeyError: 'b'

counts["b"] += 1 the first letter

↓

counts["b"] = counts["b"] + 1 the old value, plus 1

↓

counts["b"] + 1 the right side first: no key "b" yet

if ch in counts:

counts[ch] += 1

else:

counts[ch] = 1

the first time needs its own line

+= needs the old value · a new key has none yet

Counting

Counting in one line

one line

counts = {}

for ch in "banana":

counts[ch] = counts.get(ch, 0) + 1

print(counts)

counts.get("b", 0) → 0 no key "b" yet: the default

↓

0 + 1 → 1

↓

counts["b"] = 1 stored

{'b': 1, 'a': 3, 'n': 2}

four lines

if ch in counts:

counts[ch] += 1

else:

counts[ch] = 1

words, with the same line

counts = {}

for word in "the cat and the dog".split():

counts[word] = counts.get(word, 0) + 1

print(counts)

{'the': 2, 'cat': 1, 'and': 1, 'dog': 1}

get(key, 0): a missing key gives 0 · one line counts letters or words

Nested data

A list of lists

>>>table = [[85, 90], [72, 65], [93, 88]]

>>>table[1]

[72, 65]

>>>table[1][0]

72

for row in table:

print(sum(row))

175

137

181

0 1 085901726529388
nested list

a row: one list inside

table[1][0] first table[1]

↓

[72, 65][0] then [0]: 72

a list inside a list · one index, then the next

Nested data

A list of dictionaries

>>>students = [{"name": "Kim", "score": 85},

... {"name": "Lee", "score": 72}]

>>>students[1]

{'name': 'Lee', 'score': 72}

>>>students[1]["score"]

72

>>>for s in students:

... print(f"{s['name']}: {s['score']}")

...

Kim: 85

Lee: 72

>>>students["name"]

TypeError: list indices must be integers or slices, not str

0

"name"→"Kim"

"score"→85

1

"name"→"Lee"

"score"→72

a list needs a position first

students[1]["score"]: a position, then a key · from the outside in

Nested data

A dictionary of lists

>>>marks = {"Kim": [85, 90], "Lee": [72, 65]}

>>>marks["Kim"]

[85, 90]

>>>marks["Kim"][1]

90

>>>marks["Lee"].append(80)

>>>marks

{'Kim': [85, 90], 'Lee': [72, 65, 80]}

"Kim"→
8590
"Lee"→
726580

marks["Kim"][1]: a key, then a position · from the outside in

Sets

A set

>>>{3, 1, 3, 2}

{1, 2, 3}braces, no colons

>>>len(set([85, 72, 85, 93]))

3different scores

>>>sorted(set("banana"))

['a', 'b', 'n']each letter once

>>>set()

set()an empty set

>>>{}

{}an empty dictionary

1 2 3 3 duplicate: kept once

set

a set: no duplicates · no positions

Sets

in, union, intersection

>>>a = {1, 2, 3, 5}

>>>b = {2, 3, 4}

>>>4 in b

True

>>>a | b

{1, 2, 3, 4, 5}

>>>a & b

{2, 3}

union intersection
a b 1 5 2 3 4

a | b: in either set · a & b: in both

Containers

Which container?

list

[85, 72]

in order · by position

tuple

(3, 4)

fixed

dictionary

{"Kim": 85}

by key

set

{1, 2, 3}

no duplicates · in

choose by how you find a value · by position, by key, or with in

Comprehensions

A list from a for loop

scores = [85, 72, 93, 60]

a loop · week 7

one line

bonus = []

for s in scores:

bonus.append(s + 5)

>>>[s + 5 for s in scores]

[90, 77, 98, 65]

list comprehension read: s + 5, for each s in scores

high = []

for s in scores:

if s >= 80:

high.append(s)

>>>[s for s in scores if s >= 80]

[85, 93]

if at the end: only the ones that pass

read it as a loop · the value, then the for, then the if

This week

The whole program

names = ["Kim", "Lee", "Park", "Choi"]

scores = [85, 72, 93, 60]

book = dict(zip(names, scores))

for name, score in book.items():

print(f"{name}: {score}")

print(f"Average: {sum(book.values()) / len(book)}")

while True:

name = input("Name: ")

if name == "":

break

print(book.get(name, "not found"))

←dict(zip(...)): two lists → one dictionary

←items(): key and value

←values(), len

←get: the value, or a default

a dictionary finds a value by its key · as often as you need

Next steps

Next: the practice video.

Have Python open. Type everything with me.

See you in class.

← All weeks
01 / 00
Scroll · ↓ · Space