## Core methods
| Method | What it does | Returns |
|---|---|---|
| `d[key]` | Get value (KeyError if missing) | value |
| `d.get(key)` | Get value or `None` | value or None |
| `d.get(key, default)` | Get value or default | value or default |
| `d[key] = val` | Set / update key | — |
| `d.setdefault(key, default)` | Set key to default only if absent, return value | value |
| `d.update(other)` | Merge `other` into `d` (in place) | `None` |
| `d.pop(key)` | Remove and return value (KeyError if missing) | value |
| `d.pop(key, default)` | Remove and return value or default | value or default |
| `d.popitem()` | Remove and return last (key, value) pair | (key, value) |
| `d.keys()` | View of all keys | dict_keys |
| `d.values()` | View of all values | dict_values |
| `d.items()` | View of all (key, value) pairs | dict_items |
| `d.copy()` | Shallow copy | new dict |
| `d.clear()` | Remove all entries | `None` |
| `key in d` | Check if key exists | bool |
| `len(d)` | Number of key-value pairs | int |
## Dict comprehension syntax
```python
{key_expr: val_expr for var in iterable}
{key_expr: val_expr for var in iterable if condition}
{key_expr: val_expr for k, v in d.items()}
```
## Merging dicts
```python
# Python 3.5+: unpacking
merged = {**d1, **d2}
# Python 3.9+: | operator
merged = d1 | d2
d1 |= d2 # in-place
# All versions: update
d1.update(d2)
```
## Safe nested access pattern
```python
# Chain .get() to avoid KeyError at any level
value = data.get("user", {}).get("address", {}).get("city", "unknown")
```
## Common patterns
```python
# Word frequency
freq = {}
for word in text.split():
freq[word] = freq.get(word, 0) + 1
# Group items by category
groups = {}
for item in items:
groups.setdefault(item.category, []).append(item)
# Invert mapping
inv = {v: k for k, v in d.items()}
# Filter dict by value
filtered = {k: v for k, v in d.items() if v > 0}
```
Write a function `get_setting(config, key, default=None)` that safely reads a value from a config dictionary. If the key exists, return its value; otherwise return `default`. Example: `get_setting({"debug": True}, "debug")` → `True`, `get_setting({"debug": True}, "port", 8080)` → `8080`.
Write a function `word_freq(text)` that returns a dictionary mapping each word to how many times it appears. Words should be lowercased and stripped of punctuation (you can assume only spaces separate words for simplicity). Example: `word_freq("the cat sat the cat")` → `{"the": 2, "cat": 2, "sat": 1}`.
def word_freq(text):
pass
print(word_freq("the cat sat the cat"))
# {"the": 2, "cat": 2, "sat": 1}
Solution
def word_freq(text):
counts = {}
for word in text.lower().split():
counts[word] = counts.get(word, 0) + 1
return counts
print(word_freq("the cat sat the cat"))
# {"the": 2, "cat": 2, "sat": 1}
Write a function `merge(base, overrides)` that returns a new dictionary with all keys from `base`, but any key present in `overrides` takes the value from `overrides`. The original dicts must not be modified. Example: `merge({"a": 1, "b": 2}, {"b": 99, "c": 3})` → `{"a": 1, "b": 99, "c": 3}`.
Write a function `remove_key(d, key)` that removes `key` from dictionary `d` if it exists, and returns the removed value. If the key does not exist, return `None` without raising an error. The function should modify `d` in place. Example: `d = {"a": 1, "b": 2}; remove_key(d, "a")` → returns `1`, `d` becomes `{"b": 2}`.
Write a function `squares_dict(n)` using a dict comprehension that returns a dictionary where keys are integers from 1 to `n` and values are their squares. Example: `squares_dict(5)` → `{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}`.
Write a function `filter_dict(d, min_value)` that returns a new dictionary containing only the key-value pairs where the value is greater than or equal to `min_value`. Example: `filter_dict({"a": 5, "b": 1, "c": 8, "d": 3}, 4)` → `{"a": 5, "c": 8}`.
def filter_dict(d, min_value):
return {k: v for k, v in d.items() if v >= min_value}
print(filter_dict({"a": 5, "b": 1, "c": 8, "d": 3}, 4))
# {"a": 5, "c": 8}
Write a function `invert(d)` that swaps keys and values in a dictionary and returns the new inverted dict. Assume all values are unique and hashable. Example: `invert({"a": 1, "b": 2, "c": 3})` → `{1: "a", 2: "b", 3: "c"}`.
Write a function `group_by_letter(words)` that returns a dictionary where each key is a letter and the value is a sorted list of words starting with that letter. Example: `group_by_letter(["apple", "ant", "banana", "bear"])` → `{"a": ["ant", "apple"], "b": ["banana", "bear"]}`.
def group_by_letter(words):
result = {}
for word in words:
key = word[0]
result.setdefault(key, []).append(word)
for key in result:
result[key].sort()
return result
print(group_by_letter(["apple", "ant", "banana", "bear"]))
# {"a": ["ant", "apple"], "b": ["banana", "bear"]}
Write a function `deep_get(data, *keys)` that safely accesses nested dictionary values using a chain of keys. Return `None` if any key is missing. Example: `deep_get({"user": {"address": {"city": "Kyiv"}}}, "user", "address", "city")` → `"Kyiv"`, `deep_get({"user": {}}, "user", "address", "city")` → `None`.
def deep_get(data, *keys):
for key in keys:
if not isinstance(data, dict):
return None
data = data.get(key)
return data
user = {"user": {"address": {"city": "Kyiv"}}}
print(deep_get(user, "user", "address", "city")) # Kyiv
print(deep_get(user, "user", "phone")) # None
Write a function `zip_to_dict(keys, values)` that creates a dictionary from two lists of equal length. If the lists have different lengths, raise a `ValueError` with message `"Lists must have the same length"`. Example: `zip_to_dict(["a", "b", "c"], [1, 2, 3])` → `{"a": 1, "b": 2, "c": 3}`.
def zip_to_dict(keys, values):
if len(keys) != len(values):
raise ValueError("Lists must have the same length")
return dict(zip(keys, values))
print(zip_to_dict(["a", "b", "c"], [1, 2, 3]))
# {"a": 1, "b": 2, "c": 3}
try:
zip_to_dict(["x", "y"], [1, 2, 3])
except ValueError as e:
print(e)
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.