A list is an ordered, **mutable** sequence — you can change it after creation. Python provides a rich set of in-place methods that modify the list directly.
## Adding elements
```python
fruits = ["apple", "banana"]
fruits.append("cherry") # add one element at the end
print(fruits) # ["apple", "banana", "cherry"]
fruits.extend(["date", "elderberry"]) # add all elements from an iterable
print(fruits) # ["apple", "banana", "cherry", "date", "elderberry"]
fruits.insert(1, "avocado") # insert at index 1
print(fruits) # ["apple", "avocado", "banana", "cherry", "date", "elderberry"]
```
**Key difference**: `append(x)` adds `x` as a single item; `extend(iterable)` unpacks and adds each element individually. `list.append([1,2])` gives `[..., [1,2]]`, while `list.extend([1,2])` gives `[..., 1, 2]`.
## Removing elements
```python
nums = [1, 2, 3, 2, 4]
nums.remove(2) # removes the FIRST occurrence of value 2
print(nums) # [1, 3, 2, 4]
popped = nums.pop() # removes and returns the LAST element
print(popped) # 4
print(nums) # [1, 3, 2]
popped = nums.pop(0) # removes and returns element at index 0
print(popped) # 1
print(nums) # [3, 2]
nums.clear() # removes all elements
print(nums) # []
```
## Searching
```python
items = ["a", "b", "c", "b"]
print(items.index("b")) # 1 — index of FIRST match (raises ValueError if not found)
print(items.count("b")) # 2 — count of all matches
print("c" in items) # True — use `in` for simple membership check
```
## Sorting and reversing
```python
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort() # sorts in place, ascending
print(nums) # [1, 1, 2, 3, 4, 5, 6, 9]
nums.sort(reverse=True) # sorts in place, descending
print(nums) # [9, 6, 5, 4, 3, 2, 1, 1]
words = ["banana", "apple", "cherry"]
words.sort(key=len) # sort by string length
print(words) # ["apple", "banana", "cherry"]
nums.reverse() # reverses in place (does not sort)
```
`sort()` modifies in place and returns `None`. Use `sorted(lst)` if you need a new sorted list without changing the original.
## Copying
```python
original = [1, 2, 3]
copy1 = original.copy() # shallow copy
copy2 = original[:] # also a shallow copy
copy1.append(99)
print(original) # [1, 2, 3] — unchanged
print(copy1) # [1, 2, 3, 99]
```
Never do `copy = original` — that creates an **alias**, not a copy.
A tuple is an ordered, **immutable** sequence. Once created, its contents cannot change. Use tuples for data that should not be modified.
## Tuple basics
```python
point = (3, 7)
rgb = (255, 128, 0)
single = (42,) # single-element tuple — note the trailing comma!
empty = ()
print(type(point)) # <class 'tuple'>
print(point[0]) # 3
print(len(rgb)) # 3
```
Tuple without parentheses also works:
```python
coords = 10, 20 # same as (10, 20)
```
## List vs Tuple: when to use which
| List `[]` | Tuple `()` |
|---|---|
| Mutable — can add/remove/change | Immutable — fixed after creation |
| Use for collections that grow/shrink | Use for fixed records (coordinates, RGB, DB rows) |
| Slightly more memory overhead | Slightly faster access, less memory |
| Cannot be used as dict key | Can be used as dict key |
```python
# List: growing collection
shopping = []
shopping.append("milk")
shopping.append("eggs")
# Tuple: fixed record
person = ("Alice", 30, "engineer")
name, age, role = person # unpacking
```
## Tuple unpacking
```python
x, y = (10, 20)
print(x) # 10
print(y) # 20
# Swap variables without a temp variable
a, b = 1, 2
a, b = b, a
print(a, b) # 2 1
# Extended unpacking
first, *rest = [1, 2, 3, 4, 5]
print(first) # 1
print(rest) # [2, 3, 4, 5]
*start, last = [1, 2, 3, 4, 5]
print(start) # [1, 2, 3, 4]
print(last) # 5
```
## Tuple in for loops
```python
pairs = [(1, "one"), (2, "two"), (3, "three")]
for number, word in pairs:
print(f"{number} = {word}")
# 1 = one
# 2 = two
# 3 = three
```
This is how `enumerate()` and `dict.items()` work under the hood — they return tuples.
## Returning multiple values from a function
```python
def min_max(numbers):
return min(numbers), max(numbers) # returns a tuple
lo, hi = min_max([3, 1, 4, 1, 5, 9])
print(lo, hi) # 1 9
```
Functions returning multiple values always return a tuple. Unpacking is the idiomatic way to receive them.
You have a list `result = [1, 2, 3]`. Write two separate expressions:
1. Use `append` to add the list `[4, 5]` as a single item.
2. Starting fresh from `[1, 2, 3]`, use `extend` to add `[4, 5]` as individual items.
Print both results and explain the difference.
result = [1, 2, 3]
# 1. Use append to add [4, 5] as a SINGLE item
# 2. Start fresh and use extend to add [4, 5] as INDIVIDUAL items
result2 = [1, 2, 3]
Write a function `insert_after(lst, target, value)` that inserts `value` immediately after the first occurrence of `target` in `lst`. If `target` is not found, append `value` at the end. Example: `insert_after([1, 2, 4, 5], 2, 3)` → `[1, 2, 3, 4, 5]`.
Write a function `remove_dupes(lst)` that removes duplicate elements from a list while preserving the original order of first appearances. Example: `remove_dupes([3, 1, 2, 1, 3, 4])` → `[3, 1, 2, 4]`. Do not use sets directly (they do not preserve order).
def remove_dupes(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
print(remove_dupes([3, 1, 2, 1, 3, 4])) # [3, 1, 2, 4]
print(remove_dupes([1, 1, 1])) # [1]
Write a function `sort_by_length(words)` that returns a new list of words sorted by their length (shortest first). Words of equal length should remain in their original relative order. Example: `sort_by_length(["banana", "fig", "apple", "kiwi"])` → `["fig", "kiwi", "apple", "banana"]`.
Implement a simple stack using a list. Write a class `Stack` with methods: `push(item)`, `pop()` (returns and removes top item), `peek()` (returns top item without removing), `is_empty()`, and `size()`. Use only list methods — no imports needed.
The following code has a bug. Fix it so that modifying `b` does not affect `a`:
```python
a = [1, 2, 3]
b = a
b.append(99)
print(a) # should still be [1, 2, 3]
```
Explain in a comment why the original code fails.
a = [1, 2, 3]
b = a # BUG: both point to the same list
b.append(99)
print(a) # should still be [1, 2, 3], but prints [1, 2, 3, 99]
# Fix the code above so that modifying b does not affect a
Solution
a = [1, 2, 3]
b = a.copy() # creates a new independent list
b.append(99)
print(a) # [1, 2, 3] — unchanged
print(b) # [1, 2, 3, 99]
# Alternative: b = a[:] or b = list(a)
Write a function `swap(a, b)` that returns the two values swapped, using tuple unpacking in one line. Then write a function `unpack_first_last(lst)` that returns a tuple `(first, last)` using star unpacking. Example: `unpack_first_last([10, 20, 30, 40])` → `(10, 40)`.
Write a function `find_index(lst, value)` that returns the index of `value` in `lst`, or `-1` if not found. Do NOT use `.index()` directly (it raises ValueError). Example: `find_index([10, 20, 30], 20)` → `1`, `find_index([10, 20, 30], 99)` → `-1`.
Write a function `most_frequent(lst)` that returns the element that appears most often in the list. If there is a tie, return the one that appears first. Example: `most_frequent([1, 2, 2, 3, 1, 2])` → `2`, `most_frequent([5, 5, 3, 3])` → `5`.
Write a function `flatten(lst)` that takes a list of lists and returns a single flat list with all elements. Example: `flatten([[1, 2], [3, 4], [5]])` → `[1, 2, 3, 4, 5]`. Use `extend` or a list comprehension.
def flatten(lst):
result = []
for sub in lst:
result.extend(sub)
return result
# One-liner:
def flatten_v2(lst):
return [x for sub in lst for x in sub]
print(flatten([[1, 2], [3, 4], [5]])) # [1, 2, 3, 4, 5]
print(flatten([[10, 20], [30], [40, 50]])) # [10, 20, 30, 40, 50]
No split tab
Cookie preferences
We use necessary cookies to run the site. With your permission, we can also save your site preferences and use analytics and advertising cookies to understand usage and support the project.
Open tools in tabs.Exercises, IDE tools, and trainers stay available as site tabs.
Switch without losing context.Move between explanations, code, and utilities while keeping your place.
Use the sidebar as your map.The left panels hold navigation, settings, files, libraries, and tool controls.
PythonJavaScriptSQLite
One IDE, three practical modes
Python in the browser.Run small scripts, try libraries, and practice API requests without installing anything.
JavaScript for quick experiments.Test browser-friendly code and compare ideas next to your learning materials.
SQLite for data practice.Open the database explorer to inspect tables, write queries, and learn SQL workflows locally.
TopicIDE
Work side by side with split tabs
Keep instructions visible.Open an exercise or reference page beside the IDE instead of jumping back and forth.
Compare tools while you learn.Place regex checks, explanations, and code experiments next to each other when the task needs it.
Close the split when you are done.The workspace returns to a single focused tab, and your open site tabs remain available.
Code Typing Trainer
Or plain text
This trainer is designed for a physical keyboard.Open this section on a laptop or desktop with a wide screen. Touch typing practice will not work correctly on a phone.
Speed: 0 chars/min
0 words/min
Best speed (60s): 0 chars/min
0 words/min
Errors: 0
Total time: 0.0 s
To practice touch typing, avoid looking at your physical keyboard.