KAHIBARO
Discord Login Register

4.6 Data Structures

Why Data Structures Matter

In programming, a data structure is a specific way to organize and store data in memory so that you can use it efficiently.

You have already seen basic types like integers, strings, and booleans. Data structures let you:

For backend development, choosing the right data structure can be the difference between a fast, scalable API and a slow, fragile one.

Key idea: A data structure is not just what you store, but how you store it and how you work with it (add, remove, search, update).

In this chapter we will focus on concepts, with simple examples in a generic, Python-like pseudocode, but not tied to any specific language details. The Python chapter will show you concrete syntax.

Collections vs Single Values

A single value:

python
age = 25
name = "Alice"

A collection holds multiple values:

python
ages = [25, 32, 40]
names = ["Alice", "Bob", "Charlie"]

Most common collection data structures:

StructureAlso calledTypical usage
Array / ListDynamic array, listOrdered collection, index-based access
DictionaryMap, hash map, objectKey/value lookups, configs, user records
SetHash setUnique items, fast membership checks
StackLIFO"Last added, first removed"
QueueFIFO"First added, first removed"
Linked listChain of nodesSequential access, cheap insert/remove

You will meet these structures in almost every backend project, directly or indirectly.

Arrays / Lists

Concept

An array or list is an ordered collection of items. Each item has a numeric position called an index.

Example:

python
numbers = [10, 20, 30, 40]
# indexes:  0   1   2   3

Access by index:

python
first = numbers[0]   # 10
third = numbers[2]   # 30

When to use a list

Typical backend examples:

Basic operations on lists

Below is generic pseudocode that looks similar to Python.

Creating a list

python
empty = []
numbers = [1, 2, 3]
users = ["alice", "bob", "charlie"]

Reading items

python
user = users[1]   # "bob"

Changing items

python
users[1] = "bobby"
# users is now ["alice", "bobby", "charlie"]

Adding items

python
users.append("david")    # add to the end
# ["alice", "bobby", "charlie", "david"]

Removing items

python
last = users.pop()       # removes and returns last item "david"
second = users.pop(1)    # removes and returns item at index 1 "bobby"

Looping over a list

python
for user in users:
    print(user)

or with indexes:

python
for i in range(len(users)):
    print(i, users[i])

Lists and order

Lists preserve order:

python
request_log = []
request_log.append("GET /users")
request_log.append("POST /login")
request_log.append("GET /me")
# processing in order:
for entry in request_log:
    process(entry)

Dictionaries / Maps

Concept

A dictionary (often called a map or hash map) stores data as key/value pairs.

Example:

python
user = {
    "id": 123,
    "username": "alice",
    "email": "alice@example.com"
}

You look up values by key, not by position.

When to use a dictionary

Typical backend examples:

Basic operations on dictionaries

Creating a dictionary

python
user = {
    "id": 1,
    "username": "alice"
}

Accessing values

python
username = user["username"]   # "alice"

Adding or changing values

python
user["email"] = "alice@example.com"  # new key
user["username"] = "alice123"        # update existing key

Safe access

Often, you want to avoid errors when a key is missing.

python
email = user.get("email", None)  # returns None if "email" not present

Removing keys

python
removed = user.pop("email")      # remove key and get its value

Looping over a dictionary

python
for key in user:
    print(key, user[key])

Or explicitly:

python
for key, value in user.items():
    print(key, value)

Example: Caching user sessions

Imagine a simple in-memory session store:

python
sessions = {}
def create_session(session_id, user_id):
    sessions[session_id] = {"user_id": user_id}
def get_session(session_id):
    return sessions.get(session_id)
def delete_session(session_id):
    sessions.pop(session_id, None)

Here, sessions is a dictionary that maps a session_id to its session data. This pattern appears all the time in backend systems.

Rule of thumb: Use a dictionary when you need to quickly find a value by a meaningful key, like "username" or "order_id". Use a list when the numeric position of an item is enough.

Sets

Concept

A set is a collection of unique, unordered items.

Example:

python
user_ids = {1, 2, 3}

Key properties:

When to use a set

Backend examples:

Basic operations on sets

Creating a set

python
blocked_ips = {"10.0.0.1", "10.0.0.2"}
empty_set = set()

Adding items

python
blocked_ips.add("10.0.0.3")

If you add the same value again, nothing changes, because sets do not allow duplicates.

Checking membership

python
if "10.0.0.2" in blocked_ips:
    deny_request()

Removing items

python
blocked_ips.remove("10.0.0.1")   # may error if not present
blocked_ips.discard("10.0.0.9")  # no error if not present

Set operations

Sets support useful mathematical operations:

Let

python
admin_permissions = {"read_users", "delete_users", "ban_users"}
editor_permissions = {"read_users", "edit_posts"}
python
  all_permissions = admin_permissions.union(editor_permissions)
  # {"read_users", "delete_users", "ban_users", "edit_posts"}
python
  shared = admin_permissions.intersection(editor_permissions)
  # {"read_users"}
python
  only_admin = admin_permissions.difference(editor_permissions)
  # {"delete_users", "ban_users"}

These operations are very useful when implementing authorization logic.

Stacks

Concept

A stack is a collection where you can:

It follows the LIFO principle: Last In, First Out.

Think of a stack of plates. You put a plate on top and you also take the top plate first.

When to use a stack

Backend examples:

Basic stack operations

Implementation using a list:

python
stack = []
def push(item):
    stack.append(item)
def pop():
    return stack.pop()  # removes and returns last item
def peek():
    if stack:
        return stack[-1]
    return None

Usage:

python
push("first")
push("second")
top = pop()      # "second"
top2 = pop()     # "first"

Example: Undo last admin action

A very simple idea:

python
actions_stack = []
def perform_action(action):
    action.apply()
    actions_stack.append(action)
def undo_last_action():
    if actions_stack:
        last = actions_stack.pop()
        last.undo()

Here the stack keeps track of actions in the order they were done. Undo always undoes the last action first.

Queues

Concept

A queue is a collection where you:

It follows the FIFO principle: First In, First Out.

Think of people standing in line at a store. The first person in is the first person served.

When to use a queue

Backend examples:

Basic queue operations

Implementation with a list is possible, but in real code you will usually use a specialized queue structure to make operations efficient. Conceptually:

python
queue = []
def enqueue(item):
    queue.append(item)       # add to end
def dequeue():
    if queue:
        return queue.pop(0)  # remove from front
    return None

Usage:

python
enqueue("job1")
enqueue("job2")
first = dequeue()   # "job1"
second = dequeue()  # "job2"

Example: Simple email sending queue

python
email_queue = []
def queue_email(email):
    email_queue.append(email)
def process_emails():
    while email_queue:
        email = email_queue.pop(0)
        send_email(email)

In real backend systems, you will use external queues and separate worker processes, but the basic idea is the same as this simple data structure.

Linked Lists

Concept

A linked list is a sequence of nodes. Each node stores:

Example:

text
[Data A] -> [Data B] -> [Data C] -> None

In many high-level languages you will not implement linked lists manually very often, because lists (dynamic arrays) are built in and very efficient. But it is useful to understand the idea.

When to use a linked list

Backend systems usually rely on existing libraries that may use linked lists internally.

Simple conceptual implementation

python
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None
class LinkedList:
    def __init__(self):
        self.head = None
    def add_front(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node
    def iterate(self):
        current = self.head
        while current is not None:
            print(current.value)
            current = current.next

Usage:

python
ll = LinkedList()
ll.add_front("C")
ll.add_front("B")
ll.add_front("A")
# List is now A -> B -> C
ll.iterate()  # prints A, then B, then C

Again, you usually will not code this from scratch in real backend projects, but understanding it helps when reading about algorithms and performance.

Choosing the Right Data Structure

Choosing the right structure often depends on what operations must be fast.

Some common tasks and recommended structures:

Task / QuestionGood data structure
"Keep items in a specific order"List / array
"Get item number 5 quickly"List / array
"Find user by username quickly"Dictionary / map
"Store unique values and test membership quickly"Set
"Process tasks in order they arrive"Queue
"Process items in reverse order of insertion"Stack

Guideline: Think first about the operations you need (search by key, keep order, uniqueness, FIFO, LIFO). Then pick a data structure that matches those operations.

Example comparison

Suppose you have to store banned user IDs and you frequently check:

"Is user with ID X banned?"

Possible approaches:

  1. Use a list:
python
   banned = [1, 7, 42]
   if user_id in banned:
       # may be slow if list is large
  1. Use a set:
python
   banned = {1, 7, 42}
   if user_id in banned:
       # typically very fast, even for big collections

For large numbers of IDs, the set is usually the better choice.

Nested and Combined Data Structures

Real backend applications often use combinations of basic structures.

Examples:

List of dictionaries

A typical JSON-like structure:

python
users = [
    {"id": 1, "username": "alice"},
    {"id": 2, "username": "bob"}
]

You can loop over them:

python
for user in users:
    print(user["username"])

Dictionary of lists

A mapping from category to list of items:

python
products_by_category = {
    "books": ["book1", "book2"],
    "movies": ["movie1", "movie2"]
}

Dictionary of sets

Track which permissions each role has:

python
role_permissions = {
    "admin": {"read_users", "delete_users"},
    "editor": {"read_users", "edit_posts"}
}
if "delete_users" in role_permissions["admin"]:
    # allow

This is extremely common in authorization logic.

Understanding basic structures makes such nested combinations much easier to work with.

Summary

In later chapters, you will see how to express these structures in Python syntax, and how they are used in web backends, APIs, and database code.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!