Daily Tech Brief

Top startup stories in your inbox

Subscribe Free

© 2026 rakrisi Daily

Data Structures - Organizing Your Data

Data Structures: Organizing Your Data Like a Pro

Welcome to the world of data structures! Think of them as containers for your data - each with different strengths and use cases. Just like you wouldn’t carry groceries in a backpack the same way you’d carry books, different data needs different structures.

Why Data Structures Matter

Real-Life Analogy: Organizing Your Room

  • Lists: Like a shopping list - ordered items you can add/remove
  • Tuples: Like coordinates on a map - fixed, unchanging positions
  • Dictionaries: Like a phone book - name → number lookup
  • Sets: Like a guest list - unique items, order doesn’t matter

Code Benefits

# Without proper data structures (bad)
student1_name = "Alice"
student1_age = 20
student1_grade = "A"

student2_name = "Bob"
student2_age = 22
student2_grade = "B"

# With data structures (good)
students = [
    {"name": "Alice", "age": 20, "grade": "A"},
    {"name": "Bob", "age": 22, "grade": "B"}
]

Method 1: Lists - Ordered, Mutable Collections

What are Lists?

Lists are like shopping lists - ordered collections of items that you can modify.

# Creating lists
empty_list = []
numbers = [1, 2, 3, 4, 5]
fruits = ["apple", "banana", "orange"]
mixed = [1, "hello", True, 3.14]

Basic List Operations

fruits = ["apple", "banana", "orange"]

# Access elements (zero-indexed)
print(fruits[0])  # "apple"
print(fruits[1])  # "banana"
print(fruits[-1]) # "orange" (last element)

# Modify elements
fruits[1] = "grape"
print(fruits)  # ["apple", "grape", "orange"]

# Add elements
fruits.append("kiwi")        # Add to end
fruits.insert(1, "banana")   # Insert at position 1
print(fruits)  # ["apple", "banana", "grape", "orange", "kiwi"]

# Remove elements
fruits.remove("grape")       # Remove by value
popped = fruits.pop()        # Remove and return last element
print(fruits)  # ["apple", "banana", "orange"]
print(f"Popped: {popped}")  # "kiwi"

List Slicing

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Basic slicing [start:end]
print(numbers[2:5])    # [2, 3, 4]
print(numbers[:3])     # [0, 1, 2] (from start to index 3)
print(numbers[7:])     # [7, 8, 9] (from index 7 to end)

# With step [start:end:step]
print(numbers[::2])    # [0, 2, 4, 6, 8] (every 2nd element)
print(numbers[1::2])   # [1, 3, 5, 7, 9] (every 2nd starting from index 1)
print(numbers[::-1])   # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (reverse)

# Replace multiple elements
numbers[2:5] = [20, 30, 40]
print(numbers)  # [0, 1, 20, 30, 40, 5, 6, 7, 8, 9]

List Methods

fruits = ["apple", "banana", "orange", "apple"]

# Count occurrences
print(fruits.count("apple"))  # 2

# Find index
print(fruits.index("banana"))  # 1

# Sort the list
fruits.sort()
print(fruits)  # ["apple", "apple", "banana", "orange"]

# Reverse the list
fruits.reverse()
print(fruits)  # ["orange", "banana", "apple", "apple"]

# Create sorted copy without modifying original
original = ["c", "a", "b"]
sorted_copy = sorted(original)
print(original)    # ["c", "a", "b"]
print(sorted_copy) # ["a", "b", "c"]

Method 2: Tuples - Immutable Ordered Collections

What are Tuples?

Tuples are like GPS coordinates - fixed collections that cannot be changed after creation.

# Creating tuples
empty_tuple = ()
single_item = (42,)  # Note the comma!
coordinates = (10, 20)
person = ("Alice", 25, "Engineer")

# Parentheses are optional
colors = "red", "green", "blue"
print(type(colors))  # <class 'tuple'>

Tuple Operations

point = (10, 20, 30)

# Access elements (same as lists)
print(point[0])   # 10
print(point[-1])  # 30

# Slicing (same as lists)
print(point[1:])  # (20, 30)

# Tuples are immutable - cannot modify!
# point[0] = 15  # TypeError!

# But you can create new tuples
new_point = (15,) + point[1:]
print(new_point)  # (15, 20, 30)

When to Use Tuples vs Lists

# Use tuples for:
# 1. Coordinates
locations = [(40.7128, -74.0060), (34.0522, -118.2437)]  # NYC, LA

# 2. Function returns
def get_user_info():
    return ("Alice", 25, "alice@email.com")  # Always 3 values

# 3. Dictionary keys (lists cannot be keys)
student_grades = {
    ("Alice", "Smith"): "A",
    ("Bob", "Jones"): "B"
}

# Use lists for:
# 1. Collections that change
shopping_list = ["milk", "bread", "eggs"]
shopping_list.append("butter")  # Can add items

# 2. Sorting and modifying
numbers = [3, 1, 4, 1, 5]
numbers.sort()  # [1, 1, 3, 4, 5]

Method 3: Dictionaries - Key-Value Pairs

What are Dictionaries?

Dictionaries are like phone books - you look up information using keys instead of positions.

# Creating dictionaries
empty_dict = {}
person = {
    "name": "Alice",
    "age": 25,
    "city": "New York"
}

# Different key types
mixed_keys = {
    "string_key": "value",
    42: "number key",
    (1, 2): "tuple key"  # tuples can be keys, lists cannot
}

Dictionary Operations

person = {"name": "Alice", "age": 25, "city": "New York"}

# Access values
print(person["name"])  # "Alice"
print(person.get("age"))  # 25

# Safe access (no KeyError if key doesn't exist)
print(person.get("salary", "Not specified"))  # "Not specified"

# Add/modify values
person["job"] = "Engineer"
person["age"] = 26  # Update existing value
print(person)

# Remove values
removed_city = person.pop("city")
print(f"Removed: {removed_city}")
print(person)

# Check if key exists
if "name" in person:
    print("Name is in dictionary")

# Get all keys, values, or items
print(person.keys())   # dict_keys(['name', 'age', 'job'])
print(person.values()) # dict_values(['Alice', 26, 'Engineer'])
print(person.items())  # dict_items([('name', 'Alice'), ('age', 26), ('job', 'Engineer')])

Dictionary Comprehension

# Create dictionary from list
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers}
print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Filter dictionary
original = {"a": 1, "b": 2, "c": 3, "d": 4}
even_values = {k: v for k, v in original.items() if v % 2 == 0}
print(even_values)  # {"b": 2, "d": 4}

Method 4: Sets - Unique Collections

What are Sets?

Sets are like guest lists - they contain unique items and order doesn’t matter.

# Creating sets
empty_set = set()  # {} creates empty dict, not set!
numbers = {1, 2, 3, 4, 5}
fruits = {"apple", "banana", "orange"}

# From list (removes duplicates)
duplicates = [1, 2, 2, 3, 3, 3]
unique_numbers = set(duplicates)
print(unique_numbers)  # {1, 2, 3}

Set Operations

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}

# Add elements
set_a.add(6)
print(set_a)  # {1, 2, 3, 4, 5, 6}

# Remove elements
set_a.remove(6)  # Raises KeyError if not found
set_a.discard(10)  # No error if not found

# Set operations
print(set_a | set_b)  # Union: {1, 2, 3, 4, 5, 6, 7, 8}
print(set_a & set_b)  # Intersection: {4, 5}
print(set_a - set_b)  # Difference: {1, 2, 3}
print(set_a ^ set_b)  # Symmetric difference: {1, 2, 3, 6, 7, 8}

Real-World Examples

Example 1: Student Grade Book

# Using dictionaries and lists together
students = [
    {
        "name": "Alice",
        "grades": [85, 92, 88],
        "subjects": {"math": 85, "science": 92, "english": 88}
    },
    {
        "name": "Bob",
        "grades": [78, 85, 90],
        "subjects": {"math": 78, "science": 85, "english": 90}
    }
]

# Calculate average grade for each student
for student in students:
    avg_grade = sum(student["grades"]) / len(student["grades"])
    print(f"{student['name']}'s average: {avg_grade:.1f}")

# Find students who got A in math
math_a_students = [
    student["name"]
    for student in students
    if student["subjects"]["math"] >= 90
]
print(f"Math A students: {math_a_students}")

Example 2: Inventory Management

# Using sets for categories and dictionaries for products
products = {
    "laptop": {"price": 999, "stock": 5, "category": "electronics"},
    "book": {"price": 20, "stock": 50, "category": "education"},
    "headphones": {"price": 149, "stock": 12, "category": "electronics"}
}

categories = set()
for product in products.values():
    categories.add(product["category"])

print(f"Categories: {categories}")

# Find low stock items
low_stock = [
    name for name, info in products.items()
    if info["stock"] < 10
]
print(f"Low stock items: {low_stock}")

# Calculate total inventory value
total_value = sum(info["price"] * info["stock"] for info in products.values())
print(f"Total inventory value: ${total_value}")

Example 3: Social Network

# Using sets for unique relationships
social_network = {
    "Alice": {"friends": {"Bob", "Charlie"}, "interests": {"coding", "music"}},
    "Bob": {"friends": {"Alice", "Diana"}, "interests": {"music", "sports"}},
    "Charlie": {"friends": {"Alice"}, "interests": {"coding", "gaming"}},
    "Diana": {"friends": {"Bob"}, "interests": {"sports", "reading"}}
}

# Find mutual friends
alice_friends = social_network["Alice"]["friends"]
bob_friends = social_network["Bob"]["friends"]
mutual_friends = alice_friends & bob_friends
print(f"Alice and Bob's mutual friends: {mutual_friends}")

# Find people with shared interests
def find_shared_interests(person1, person2):
    interests1 = social_network[person1]["interests"]
    interests2 = social_network[person2]["interests"]
    return interests1 & interests2

shared = find_shared_interests("Alice", "Bob")
print(f"Alice and Bob's shared interests: {shared}")

# Suggest friends based on mutual friends
def suggest_friends(person):
    friends = social_network[person]["friends"]
    suggestions = set()

    for friend in friends:
        friend_friends = social_network[friend]["friends"]
        # Add friends of friends (excluding self and direct friends)
        suggestions.update(friend_friends - friends - {person})

    return suggestions

alice_suggestions = suggest_friends("Alice")
print(f"Friend suggestions for Alice: {alice_suggestions}")

Common Data Structure Patterns

Pattern 1: Counter

# Count word frequencies
text = "the quick brown fox jumps over the lazy dog the fox is quick"
words = text.split()
word_count = {}

for word in words:
    word_count[word] = word_count.get(word, 0) + 1

print(word_count)
# {'the': 2, 'quick': 2, 'brown': 1, 'fox': 2, 'jumps': 1, 'over': 1, 'lazy': 1, 'dog': 1, 'is': 1}

Pattern 2: Group By

# Group students by grade
students = [
    {"name": "Alice", "grade": "A"},
    {"name": "Bob", "grade": "B"},
    {"name": "Charlie", "grade": "A"},
    {"name": "Diana", "grade": "C"}
]

grade_groups = {}
for student in students:
    grade = student["grade"]
    if grade not in grade_groups:
        grade_groups[grade] = []
    grade_groups[grade].append(student["name"])

print(grade_groups)
# {'A': ['Alice', 'Charlie'], 'B': ['Bob'], 'C': ['Diana']}

Pattern 3: Stack (LIFO)

# Browser back button simulation
browser_history = []

def visit_page(page):
    browser_history.append(page)
    print(f"Visited: {page}")

def go_back():
    if browser_history:
        last_page = browser_history.pop()
        print(f"Went back from: {last_page}")
        if browser_history:
            print(f"Now on: {browser_history[-1]}")
        else:
            print("No more pages in history")
    else:
        print("Cannot go back - no history")

visit_page("google.com")
visit_page("github.com")
visit_page("stackoverflow.com")
go_back()
go_back()
go_back()
go_back()  # Try to go back too many times

Pattern 4: Queue (FIFO)

# Print job queue
print_queue = []

def add_print_job(document):
    print_queue.append(document)
    print(f"Added to queue: {document}")

def process_print_job():
    if print_queue:
        job = print_queue.pop(0)  # Remove from front
        print(f"Printing: {job}")
    else:
        print("No jobs in queue")

add_print_job("report.pdf")
add_print_job("presentation.pptx")
add_print_job("resume.docx")
process_print_job()
process_print_job()
process_print_job()
process_print_job()  # Try to process when queue is empty

Performance Considerations

Time Complexity

# List operations
my_list = [1, 2, 3, 4, 5]
my_list.append(6)        # O(1) - fast
my_list.insert(0, 0)     # O(n) - slow for large lists
5 in my_list            # O(n) - slow for large lists

# Dictionary operations
my_dict = {"a": 1, "b": 2}
my_dict["c"] = 3         # O(1) - fast
"c" in my_dict          # O(1) - fast
my_dict["c"]            # O(1) - fast

# Set operations
my_set = {1, 2, 3}
my_set.add(4)           # O(1) - fast
4 in my_set             # O(1) - fast

Practice Exercises

Exercise 1: To-Do List Application

Create a to-do list that supports:

  • Adding tasks
  • Marking tasks as complete
  • Removing tasks
  • Listing all/active/completed tasks

Exercise 2: Student Grade Analyzer

Create a system that:

  • Stores student information (name, grades, subjects)
  • Calculates averages
  • Finds top performers
  • Groups students by grade ranges

Exercise 3: Library Management System

Build a library system with:

  • Books (title, author, ISBN, available copies)
  • Members (name, ID, borrowed books)
  • Borrowing/returning functionality
  • Search by title/author

Exercise 4: Recipe Manager

Create a recipe manager that:

  • Stores recipes (name, ingredients, instructions)
  • Searches recipes by ingredient
  • Suggests recipes based on available ingredients
  • Scales recipes for different servings

Exercise 5: Music Playlist Manager

Build a playlist system with:

  • Songs (title, artist, album, duration)
  • Playlists (name, songs)
  • Add/remove songs from playlists
  • Calculate total playlist duration
  • Find songs by artist/album

Summary

Data structures are the foundation of organized programming:

  • Lists: Ordered, mutable collections [1, 2, 3]
  • Tuples: Ordered, immutable collections (1, 2, 3)
  • Dictionaries: Key-value pairs {"key": "value"}
  • Sets: Unique, unordered collections {1, 2, 3}

Choose the right structure for your needs:

  • Use lists for ordered collections that change
  • Use tuples for fixed collections of related data
  • Use dictionaries for named data with fast lookup
  • Use sets for unique items and mathematical operations

Next: Advanced Data Structures - stacks, queues, and trees! 🌳