Lists - Your Shopping List

A list is like a shopping list on your phone. You can add items, remove items, check what's first, or see how many items you have.
A list is a collection that stores multiple items in a single variable. Think of it as a numbered container where each item has a position (index). Lists are **ordered**, **mutable** (you can change them), and can contain any type of data – numbers, strings, even other lists.

**Creating a list:**
Use square brackets `[]` with items separated by commas:
```python
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [42, "hello", 3.14, True]
```

**Accessing elements (indexing):**
Python uses **zero‑based indexing** – the first item is at index 0.
```python
fruits[0] # 'apple'
fruits[1] # 'banana'
fruits[2] # 'cherry'
```
Negative indices count from the end:
```python
fruits[-1] # 'cherry' (last item)
fruits[-2] # 'banana'
```

**Slicing a list:**
Extract a sublist with `[start:end:step]`.
```python
fruits[0:2] # ['apple', 'banana'] (end index is exclusive)
fruits[:2] # ['apple', 'banana'] (from start)
fruits[1:] # ['banana', 'cherry'] (to end)
fruits[::-1] # ['cherry', 'banana', 'apple'] (reverse)
```

**Common list methods:**
- `.append(item)` – adds an item to the end.
- `.insert(index, item)` – inserts an item at a specific position.
- `.remove(item)` – removes the first occurrence of that item.
- `.pop(index)` – removes and returns the item at the given index (default last).
- `.sort()` – sorts the list in place (numbers ascending, strings alphabetically).
- `.reverse()` – reverses the list in place.
- `.index(item)` – returns the index of the first occurrence.
- `.count(item)` – returns how many times the item appears.
- `.clear()` – removes all items.

**Built‑in functions for lists:**
- `len(list)` – returns the number of items.
- `sum(list)` – sum of numeric items.
- `min(list)` – smallest item.
- `max(list)` – largest item.
- `sorted(list)` – returns a new sorted list (original unchanged).

**Looping through a list:**
```python
for item in my_list:
print(item)
```
If you also need the index, use `enumerate()`:
```python
for index, item in enumerate(my_list):
print(f"{index}: {item}")
```

**List comprehension (advanced but powerful):**
Create a new list by applying an expression to each item:
```python
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
```

**Common mistakes:**
- Forgetting that indexing starts at 0 – `list[1]` is the second element.
- Using `=` instead of `.append()` to add an item (overwrites the list).
- Modifying a list while iterating over it – can cause unexpected behavior.
- Using `.remove()` on an item that doesn't exist – raises `ValueError`.
- Confusing `.sort()` (modifies original) with `sorted()` (returns new list).

**Real‑world applications:**
- Storing user names or IDs.
- Keeping track of scores in a game.
- Managing a to‑do list or shopping cart.
- Processing batches of data from files or APIs.
- Implementing stacks (`.append()` / `.pop()`) or queues.

**Practice exercises:**
1. Create a list of five favorite movies. Print the first, third, and last movie.
2. Add a new movie to the end, then insert another at position 2. Remove the last movie.
3. Create a list of numbers, sort it, then reverse it.
4. Ask the user for 5 numbers, store them in a list, and print the sum and average.
5. Write a program that removes duplicates from a list (hint: convert to set then back to list).
6. Check if a specific item exists in a list using the `in` operator.

**Example with `in` operator:**
```python
if "apple" in fruits:
print("We have apples!")
```
# ========== EXAMPLE 1: Creating, Accessing, and Modifying Lists ==========
print("=== Example 1: Basic List Operations ===")
shopping_list = ["apples", "milk", "bread", "eggs"]
print(f"My shopping list: {shopping_list}")

# Accessing items (zero‑based index)
print(f"First item: {shopping_list[0]}")   # apples
print(f"Third item: {shopping_list[2]}")   # bread
print(f"Last item: {shopping_list[-1]}")   # eggs

# Adding items
shopping_list.append("cheese")
print(f"After adding cheese: {shopping_list}")

# Removing items
shopping_list.remove("bread")
print(f"After removing bread: {shopping_list}")
print()

# ========== EXAMPLE 2: List Length, Looping, and Sorting ==========
print("=== Example 2: Looping, Length, and Sorting ===")
print(f"Number of items: {len(shopping_list)}")

print("\nI need to buy:")
for item in shopping_list:
    print(f"- {item}")

# Sorting numbers
numbers = [5, 2, 8, 1, 9]
print(f"\nOriginal numbers: {numbers}")
numbers.sort()
print(f"Sorted numbers: {numbers}")
numbers.reverse()
print(f"Reversed numbers: {numbers}")
print()

# ========== EXAMPLE 3: Advanced List Methods (Insert, Pop, Index, Count) ==========
print("=== Example 3: Insert, Pop, Index, and Count ===")
tasks = ["write code", "test", "debug"]
print(f"Tasks: {tasks}")

# Insert at specific position
tasks.insert(1, "plan")
print(f"After insert at index 1: {tasks}")

# Pop removes and returns the last item
last = tasks.pop()
print(f"Popped item: '{last}', remaining: {tasks}")

# Find index of an item
idx = tasks.index("test")
print(f"'test' is at index {idx}")

# Count occurrences
tasks.append("write code")
count = tasks.count("write code")
print(f"'write code' appears {count} time(s)")

# Check membership with `in`
if "debug" in tasks:
    print("Debug is still in the list")
else:
    print("Debug was removed")

→ Run this code interactively