# Chapter 5: Data Structures

Python provides several built-in data structures that make it easy to organize, manipulate, and store data. These include lists, tuples, dictionaries, and sets. Understanding these structures is essential for writing efficient and readable code.

#### Lists

A list is a mutable, ordered collection of items. Lists can store elements of different data types.

**Creating a List:**

```python
# An empty list
my_list = []

# A list with integers
numbers = [1, 2, 3, 4, 5]

# A mixed-type list
mixed = [1, "hello", 3.14, True]
```

**Accessing Elements:**

Elements in a list can be accessed using indices (starting from 0).

```python
numbers = [10, 20, 30, 40]
print(numbers[0])  # Output: 10
print(numbers[-1])  # Output: 40 (last element)
```

**Modifying Lists:**

```python
numbers[1] = 25
print(numbers)  # Output: [10, 25, 30, 40]
```

**List Methods:**

| **Method**     | **Description**                                              |
| -------------- | ------------------------------------------------------------ |
| `append(x)`    | Adds `x` to the end of the list.                             |
| `insert(i, x)` | Inserts `x` at index `i`.                                    |
| `remove(x)`    | Removes the first occurrence of `x`.                         |
| `pop(i)`       | Removes and returns the element at index `i` (default last). |
| `sort()`       | Sorts the list in ascending order.                           |
| `reverse()`    | Reverses the list.                                           |

**Example:**

```python
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
print(fruits)  # Output: ['apple', 'banana', 'cherry', 'orange']

fruits.remove("banana")
print(fruits)  # Output: ['apple', 'cherry', 'orange']

fruits.sort()
print(fruits)  # Output: ['apple', 'cherry', 'orange']
```

#### Tuples

A tuple is an immutable, ordered collection of items. Once created, its elements cannot be changed.

**Creating a Tuple:**

```python
# An empty tuple
empty_tuple = ()

# A tuple with elements
numbers = (1, 2, 3, 4)

# A single-element tuple (note the comma)
single = (5,)
```

**Accessing Elements:**

```python
print(numbers[1])  # Output: 2
print(numbers[-1])  # Output: 4
```

**Immutability:**

Tuples cannot be modified after creation. Attempting to do so will raise an error.

```python
numbers[1] = 10  # TypeError: 'tuple' object does not support item assignment
```

**Use Cases:**

* Representing fixed collections of items (e.g., coordinates).
* Using as keys in dictionaries (immutable requirement).

#### Dictionaries

A dictionary is an unordered collection of key-value pairs. Keys must be unique and immutable.

**Creating a Dictionary:**

```python
# An empty dictionary
data = {}

# A dictionary with key-value pairs
person = {
    "name": "Alice",
    "age": 25,
    "city": "New York"
}
```

**Accessing Values:**

```python
print(person["name"])  # Output: Alice
```

**Modifying a Dictionary:**

```python
person["age"] = 26
print(person)  # Output: {'name': 'Alice', 'age': 26, 'city': 'New York'}
```

**Dictionary Methods:**

| **Method**          | **Description**                           |
| ------------------- | ----------------------------------------- |
| `keys()`            | Returns a view of all keys.               |
| `values()`          | Returns a view of all values.             |
| `items()`           | Returns a view of all key-value pairs.    |
| `get(key, default)` | Returns the value for `key` or `default`. |
| `pop(key)`          | Removes and returns the value for `key`.  |

**Example:**

```python
person = {"name": "Bob", "age": 30}
person["city"] = "London"
print(person)  # Output: {'name': 'Bob', 'age': 30, 'city': 'London'}

print(person.keys())  # Output: dict_keys(['name', 'age', 'city'])
```

#### Sets

A set is an unordered collection of unique elements.

**Creating a Set:**

```python
# An empty set
empty_set = set()

# A set with elements
numbers = {1, 2, 3, 4}
```

**Adding and Removing Elements:**

```python
numbers.add(5)
print(numbers)  # Output: {1, 2, 3, 4, 5}

numbers.remove(3)
print(numbers)  # Output: {1, 2, 4, 5}
```

**Set Operations:**

| **Operation**  | **Description**                                     | **Example** |
| -------------- | --------------------------------------------------- | ----------- |
| Union          | Combines elements from both sets.                   | \`a         |
| Intersection   | Returns common elements.                            | `a & b`     |
| Difference     | Returns elements in `a` but not in `b`.             | `a - b`     |
| Symmetric Diff | Returns elements in either `a` or `b` but not both. | `a ^ b`     |

**Example:**

```python
a = {1, 2, 3}
b = {3, 4, 5}

print(a | b)  # Union: {1, 2, 3, 4, 5}
print(a & b)  # Intersection: {3}
print(a - b)  # Difference: {1, 2}
print(a ^ b)  # Symmetric Difference: {1, 2, 4, 5}
```

#### Summary of Differences

| **Data Structure** | **Mutable** | **Ordered** | **Allows Duplicates** |
| ------------------ | ----------- | ----------- | --------------------- |
| List               | Yes         | Yes         | Yes                   |
| Tuple              | No          | Yes         | Yes                   |
| Dictionary         | Yes         | No          | No (keys)             |
| Set                | Yes         | No          | No                    |

#### Exercises

**Exercise 1:**

Create a list of numbers and perform the following operations: add a number, remove a number, and sort the list.

**Solution:**

```python
numbers = [5, 2, 9, 1]
numbers.append(7)
numbers.remove(2)
numbers.sort()
print(numbers)  # Output: [1, 5, 7, 9]
```

**Exercise 2:**

Create a dictionary representing a student (name, age, and grade) and update their grade.

**Solution:**

```python
student = {"name": "John", "age": 20, "grade": "B"}
student["grade"] = "A"
print(student)  # Output: {'name': 'John', 'age': 20, 'grade': 'A'}
```

**Exercise 3:**

Create two sets and find their union, intersection, and difference.

**Solution:**

```python
set1 = {1, 2, 3}
set2 = {3, 4, 5}

print(set1 | set2)  # Union: {1, 2, 3, 4, 5}
print(set1 & set2)  # Intersection: {3}
print(set1 - set2)  # Difference: {1, 2}
```

In the next chapter, we will explore object-oriented programming (OOP) in Python, including classes, objects, and principles like inheritance and encapsulation.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://py.d19.in/chapter-5-data-structures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
