Skip to main content

Dictionaries and Sets

Dictionaryโ€‹

Dictionaries are mutable data structures that store data as key-value pairs.

Creating Dictionariesโ€‹

# Empty dictionary
empty = {}
empty = dict()

# Dictionary with values
person = {
"name": "ํ™๊ธธ๋™",
"age": 25,
"city": "์„œ์šธ"
}

# dict() function
person = dict(name="ํ™๊ธธ๋™", age=25, city="์„œ์šธ")

# Convert from list
pairs = [("name", "ํ™๊ธธ๋™"), ("age", 25)]
person = dict(pairs)

# Create keys
keys = ["a", "b", "c"]
values = [1, 2, 3]
result = dict(zip(keys, values))
print(result) # {'a': 1, 'b': 2, 'c': 3}

# Set default values with fromkeys
keys = ["a", "b", "c"]
result = dict.fromkeys(keys, 0)
print(result) # {'a': 0, 'b': 0, 'c': 0}

Accessing Dictionariesโ€‹

person = {"name": "ํ™๊ธธ๋™", "age": 25, "city": "์„œ์šธ"}

# Access by key
print(person["name"]) # ํ™๊ธธ๋™
print(person["age"]) # 25

# get() method (safe)
print(person.get("name")) # ํ™๊ธธ๋™
print(person.get("phone")) # None (key doesn't exist)
print(person.get("phone", "์—†์Œ")) # ์—†์Œ (default value)

# Check key existence
print("name" in person) # True
print("phone" in person) # False

# All keys, values, pairs
print(person.keys()) # dict_keys(['name', 'age', 'city'])
print(person.values()) # dict_values(['ํ™๊ธธ๋™', 25, '์„œ์šธ'])
print(person.items()) # dict_items([('name', 'ํ™๊ธธ๋™'), ...])

# Convert to list
keys_list = list(person.keys())
values_list = list(person.values())

Modifying Dictionariesโ€‹

person = {"name": "ํ™๊ธธ๋™", "age": 25}

# Add/modify value
person["city"] = "์„œ์šธ" # Add
person["age"] = 26 # Modify
print(person)

# update() - Add/modify multiple values
person.update({"age": 27, "job": "๊ฐœ๋ฐœ์ž"})
print(person)

person.update(age=28, phone="010-1234-5678")
print(person)

# setdefault - Add only if key doesn't exist
person.setdefault("city", "๋ถ€์‚ฐ") # Ignore if exists
print(person["city"]) # ์„œ์šธ (keep existing value)

person.setdefault("hobby", "๋…์„œ") # Add if not exists
print(person["hobby"]) # ๋…์„œ

# Delete value
del person["hobby"] # Delete by key
age = person.pop("age") # Delete and return value
print(age) # 28

# Delete last item (Python 3.7+ maintains insertion order)
item = person.popitem()
print(item) # ('phone', '010-1234-5678')

# Clear all
person.clear()
print(person) # {}

Iterating Dictionariesโ€‹

person = {"name": "ํ™๊ธธ๋™", "age": 25, "city": "์„œ์šธ"}

# Iterate over keys
for key in person:
print(key)

# Keys explicitly
for key in person.keys():
print(key)

# Iterate over values
for value in person.values():
print(value)

# Iterate over key-value pairs (most common)
for key, value in person.items():
print(f"{key}: {value}")

# With index
for index, (key, value) in enumerate(person.items()):
print(f"{index+1}. {key}: {value}")

Dictionary Comprehensionโ€‹

# Basic form
squares = {x: x**2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# With condition
even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

# String length
words = ["apple", "banana", "cherry"]
lengths = {word: len(word) for word in words}
print(lengths) # {'apple': 5, 'banana': 6, 'cherry': 6}

# Swap keys and values
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped) # {1: 'a', 2: 'b', 3: 'c'}

# Conditional transformation
scores = {"ํ™๊ธธ๋™": 85, "๊น€์ฒ ์ˆ˜": 92, "์ด์˜ํฌ": 78}
grades = {name: "Pass" if score >= 80 else "Fail"
for name, score in scores.items()}
print(grades)

Nested Dictionariesโ€‹

# Student information
students = {
"2024001": {
"name": "ํ™๊ธธ๋™",
"age": 20,
"scores": {"math": 85, "english": 90}
},
"2024002": {
"name": "๊น€์ฒ ์ˆ˜",
"age": 21,
"scores": {"math": 92, "english": 88}
}
}

# Access
print(students["2024001"]["name"]) # ํ™๊ธธ๋™
print(students["2024001"]["scores"]["math"]) # 85

# Iteration
for student_id, info in students.items():
print(f"ID: {student_id}")
print(f"์ด๋ฆ„: {info['name']}")
avg = sum(info['scores'].values()) / len(info['scores'])
print(f"ํ‰๊ท : {avg:.1f}")
print()

Setโ€‹

Sets are unordered collections that don't allow duplicates.

Creating Setsโ€‹

# Empty set (Note: {} is a dictionary!)
empty = set()

# Set with values
numbers = {1, 2, 3, 4, 5}
fruits = {"์‚ฌ๊ณผ", "๋ฐ”๋‚˜๋‚˜", "์ฒด๋ฆฌ"}

# Duplicates are automatically removed
numbers = {1, 2, 2, 3, 3, 3}
print(numbers) # {1, 2, 3}

# Convert from other types
numbers = set([1, 2, 2, 3, 4, 4, 5])
print(numbers) # {1, 2, 3, 4, 5}

chars = set("hello")
print(chars) # {'h', 'e', 'l', 'o'} - duplicates removed

Set Operationsโ€‹

# Add element
fruits = {"์‚ฌ๊ณผ", "๋ฐ”๋‚˜๋‚˜"}
fruits.add("์ฒด๋ฆฌ")
print(fruits) # {'์‚ฌ๊ณผ', '๋ฐ”๋‚˜๋‚˜', '์ฒด๋ฆฌ'}

# Add multiple elements
fruits.update(["ํฌ๋„", "๋ฉœ๋ก "])
print(fruits)

# Delete element
fruits.remove("๋ฐ”๋‚˜๋‚˜") # Error if not exists
fruits.discard("์ˆ˜๋ฐ•") # No error if not exists
popped = fruits.pop() # Remove arbitrary element
fruits.clear() # Clear all

# Check membership
numbers = {1, 2, 3, 4, 5}
print(3 in numbers) # True
print(10 in numbers) # False

# Length
print(len(numbers)) # 5

Set Operationsโ€‹

a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}

# Union
print(a | b) # {1, 2, 3, 4, 5, 6, 7, 8}
print(a.union(b)) # Same result

# Intersection
print(a & b) # {4, 5}
print(a.intersection(b)) # Same result

# Difference
print(a - b) # {1, 2, 3}
print(a.difference(b)) # Same result

# Symmetric difference
print(a ^ b) # {1, 2, 3, 6, 7, 8}
print(a.symmetric_difference(b)) # Same result

# Subset/superset
small = {1, 2}
large = {1, 2, 3, 4}
print(small.issubset(large)) # True
print(large.issuperset(small)) # True
print(small.isdisjoint({5, 6})) # True (no intersection)

Set Comprehensionโ€‹

# Basic form
squares = {x**2 for x in range(1, 6)}
print(squares) # {1, 4, 9, 16, 25}

# With condition
even_nums = {x for x in range(1, 11) if x % 2 == 0}
print(even_nums) # {2, 4, 6, 8, 10}

# String processing
text = "hello world"
unique_chars = {c.upper() for c in text if c.isalpha()}
print(unique_chars) # {'H', 'E', 'L', 'O', 'W', 'R', 'D'}

frozenset (Immutable Set)โ€‹

# Immutable set
immutable = frozenset([1, 2, 3, 4, 5])
print(immutable)

# Cannot modify
# immutable.add(6) # โŒ AttributeError

# Can be used as dictionary key
data = {
frozenset([1, 2]): "group1",
frozenset([3, 4]): "group2"
}
print(data[frozenset([1, 2])]) # group1

Practical Examplesโ€‹

Word Frequency Analysisโ€‹

def word_frequency(text):
"""Calculate word frequency"""
# Convert to lowercase and split
words = text.lower().split()

# Count frequency
frequency = {}
for word in words:
frequency[word] = frequency.get(word, 0) + 1

# Sort by frequency
sorted_freq = sorted(frequency.items(),
key=lambda x: x[1],
reverse=True)

return dict(sorted_freq)

text = """
Python is a popular programming language.
Python is easy to learn.
Many developers use Python.
"""

result = word_frequency(text)
print("=== ๋‹จ์–ด ๋นˆ๋„ ===")
for word, count in result.items():
print(f"{word}: {count}ํšŒ")

Phone Bookโ€‹

class PhoneBook:
def __init__(self):
self.contacts = {}

def add(self, name, phone):
"""Add contact"""
self.contacts[name] = phone
print(f"{name} ์ถ”๊ฐ€๋จ")

def get(self, name):
"""Get contact"""
return self.contacts.get(name, "๋“ฑ๋ก๋˜์ง€ ์•Š์Œ")

def update(self, name, phone):
"""Update contact"""
if name in self.contacts:
self.contacts[name] = phone
print(f"{name} ์ˆ˜์ •๋จ")
else:
print(f"{name}์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ")

def remove(self, name):
"""Remove contact"""
if name in self.contacts:
del self.contacts[name]
print(f"{name} ์‚ญ์ œ๋จ")
else:
print(f"{name}์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ")

def list_all(self):
"""List all contacts"""
if not self.contacts:
print("๋“ฑ๋ก๋œ ์—ฐ๋ฝ์ฒ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค")
return

print("\n=== ์ „ํ™”๋ฒˆํ˜ธ๋ถ€ ===")
for name, phone in sorted(self.contacts.items()):
print(f"{name}: {phone}")

# Usage
phonebook = PhoneBook()
phonebook.add("ํ™๊ธธ๋™", "010-1234-5678")
phonebook.add("๊น€์ฒ ์ˆ˜", "010-2345-6789")
phonebook.list_all()
print(f"\nํ™๊ธธ๋™: {phonebook.get('ํ™๊ธธ๋™')}")

Remove Duplicates and Analyzeโ€‹

def analyze_data(data):
"""Analyze data"""
# Remove duplicates
unique = set(data)

# Statistics
stats = {
"์ „์ฒด": len(data),
"๊ณ ์œ ๊ฐ’": len(unique),
"์ค‘๋ณต": len(data) - len(unique),
"์ตœ๋Œ€": max(data),
"์ตœ์†Œ": min(data),
"์ค‘๋ณต๊ฐ’": [x for x in unique if data.count(x) > 1]
}

return stats

data = [1, 2, 2, 3, 3, 3, 4, 5, 5]
result = analyze_data(data)

print("=== ๋ฐ์ดํ„ฐ ๋ถ„์„ ===")
for key, value in result.items():
print(f"{key}: {value}")

Student Grade Managementโ€‹

class GradeManager:
def __init__(self):
self.students = {}

def add_student(self, name):
"""Add student"""
if name not in self.students:
self.students[name] = {}
print(f"{name} ์ถ”๊ฐ€๋จ")

def add_score(self, name, subject, score):
"""Add score"""
if name not in self.students:
self.add_student(name)
self.students[name][subject] = score

def get_average(self, name):
"""Calculate average"""
if name not in self.students or not self.students[name]:
return 0
scores = self.students[name].values()
return sum(scores) / len(scores)

def get_subject_average(self, subject):
"""Subject average"""
scores = [student[subject]
for student in self.students.values()
if subject in student]
if not scores:
return 0
return sum(scores) / len(scores)

def get_ranking(self):
"""Calculate ranking"""
averages = {name: self.get_average(name)
for name in self.students}
return sorted(averages.items(),
key=lambda x: x[1],
reverse=True)

def show_report(self):
"""Show report card"""
print("\n=== ์„ฑ์ ํ‘œ ===")
for name, scores in self.students.items():
print(f"\n{name}:")
for subject, score in scores.items():
print(f" {subject}: {score}์ ")
print(f" ํ‰๊ท : {self.get_average(name):.1f}์ ")

# Usage
manager = GradeManager()
manager.add_score("ํ™๊ธธ๋™", "์ˆ˜ํ•™", 85)
manager.add_score("ํ™๊ธธ๋™", "์˜์–ด", 90)
manager.add_score("๊น€์ฒ ์ˆ˜", "์ˆ˜ํ•™", 92)
manager.add_score("๊น€์ฒ ์ˆ˜", "์˜์–ด", 88)

manager.show_report()

print("\n=== ์ˆœ์œ„ ===")
for rank, (name, avg) in enumerate(manager.get_ranking(), 1):
print(f"{rank}. {name}: {avg:.1f}์ ")

Tag Systemโ€‹

class TagSystem:
def __init__(self):
self.items = {} # {item_id: {tags}}
self.tags = {} # {tag: {item_ids}}

def add_item(self, item_id, tags):
"""Add item with tags"""
self.items[item_id] = set(tags)
for tag in tags:
if tag not in self.tags:
self.tags[tag] = set()
self.tags[tag].add(item_id)

def find_by_tag(self, tag):
"""Find items by tag"""
return self.tags.get(tag, set())

def find_by_tags(self, tags, mode="any"):
"""Find by multiple tags"""
if not tags:
return set()

tag_sets = [self.tags.get(tag, set()) for tag in tags]

if mode == "any": # OR condition
return set.union(*tag_sets) if tag_sets else set()
else: # AND condition
return set.intersection(*tag_sets) if tag_sets else set()

def get_related_tags(self, tag):
"""Find related tags"""
items = self.find_by_tag(tag)
related = set()
for item in items:
related.update(self.items[item])
related.discard(tag)
return related

# Usage
tags = TagSystem()
tags.add_item("post1", ["python", "tutorial", "beginner"])
tags.add_item("post2", ["python", "advanced", "performance"])
tags.add_item("post3", ["javascript", "tutorial", "beginner"])

print("Python ํƒœ๊ทธ:", tags.find_by_tag("python"))
print("Tutorial + Beginner:", tags.find_by_tags(["tutorial", "beginner"], "all"))
print("Python ๊ด€๋ จ ํƒœ๊ทธ:", tags.get_related_tags("python"))

Frequently Asked Questionsโ€‹

Q1. What types can be used as dictionary keys?โ€‹

A: Only immutable types are allowed

# โœ… Allowed
d = {
"string": 1,
42: 2,
3.14: 3,
(1, 2): 4,
frozenset([1, 2]): 5
}

# โŒ Not allowed
# d = {[1, 2]: 1} # List not allowed
# d = {{1, 2}: 1} # Set not allowed
# d = {{"a": 1}: 1} # Dictionary not allowed

Q2. Do dictionaries have order?โ€‹

A: Python 3.7+ maintains insertion order

# Python 3.7+
d = {"c": 3, "a": 1, "b": 2}
print(list(d.keys())) # ['c', 'a', 'b'] - insertion order

# If sorting needed, do it explicitly
sorted_d = dict(sorted(d.items()))
print(list(sorted_d.keys())) # ['a', 'b', 'c']

Q3. Can't access sets by index?โ€‹

A: No, they're unordered so indexing is not possible

s = {1, 2, 3}
# print(s[0]) # โŒ TypeError

# Convert to list or use loop
s_list = list(s)
print(s_list[0]) # โœ…

for item in s: # โœ…
print(item)

Q4. How to set default values for dictionary values?โ€‹

A: Use defaultdict

from collections import defaultdict

# Regular dictionary
normal = {}
# normal["key"] += 1 # โŒ KeyError

# defaultdict
counter = defaultdict(int) # Default value 0
counter["key"] += 1 # โœ…
print(counter["key"]) # 1

groups = defaultdict(list) # Default value []
groups["a"].append(1) # โœ…
print(groups) # {'a': [1]}

Next Stepsโ€‹

You've mastered dictionaries and sets!

Key Takeaways:
โœ… Dictionary: Key-value pairs, fast lookup
โœ… Set: Remove duplicates, set operations
โœ… Comprehensions for concise creation
โœ… Practical applications (frequency analysis, tag system, etc.)

Next Step: Learn how to control program flow in Conditionals and Loops!