[{"data":1,"prerenderedAt":76},["ShallowReactive",2],{"qa-\u002Fpython\u002Fdata-structures\u002Fdictionaries":3},{"page":4,"siblings":56,"blog":73},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":48,"seo":49,"seoDescription":50,"stem":51,"subtopic":6,"topic":52,"topicSlug":53,"updated":54,"__hash__":55},"qa\u002Fpython\u002Fdata-structures\u002Fdictionaries.md","Dictionaries",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,3,"\u002Fpython\u002Fdata-structures\u002Fdictionaries",[23,28,32,36,40,44],{"id":24,"difficulty":25,"q":26,"a":27},"insertion-ordering","easy","Are Python dictionaries ordered?","Yes. Since **Python 3.7**, dictionaries **preserve insertion order** as a\n**language guarantee** — iterating a dict yields keys in the order they were\nfirst added. (This was an implementation detail in CPython 3.6, then made\nofficial in 3.7.)\n\n```python\nd = {}\nd[\"b\"] = 1\nd[\"a\"] = 2\nd[\"c\"] = 3\nlist(d)            # ['b', 'a', 'c'] — insertion order, not sorted\n\nd[\"b\"] = 9         # updating a value does NOT change order\nlist(d)            # ['b', 'a', 'c']\n```\n\nNote that **updating** an existing key keeps its original position; only the\nfirst insertion fixes the order. Reassigning doesn't move it. Because ordering\nis guaranteed, plain `dict` now covers most cases that once needed\n`OrderedDict`.\n",{"id":29,"difficulty":25,"q":30,"a":31},"get-vs-bracket-setdefault","What is the difference between d[key], d.get(key), and d.setdefault()?","**`d[key]`** raises `KeyError` if the key is missing. **`d.get(key, default)`**\nreturns a default (or `None`) instead of raising — a safe read.\n**`d.setdefault(key, default)`** returns the existing value if present, but if\nmissing it **inserts** the default and returns it.\n\n```python\nd = {\"a\": 1}\nd[\"b\"]               # KeyError\nd.get(\"b\")           # None — no error\nd.get(\"b\", 0)        # 0   — supplied default\n\nd.setdefault(\"a\", 99)  # 1  — already present, unchanged\nd.setdefault(\"c\", []).append(5)  # inserts c=[], then appends -> {'c': [5]}\n```\n\nUse `get` for a safe lookup that **doesn't mutate**, and `setdefault` to\n**read-or-initialize** in one step (handy for grouping). For heavy grouping work,\n`collections.defaultdict` is usually cleaner.\n",{"id":33,"difficulty":14,"q":34,"a":35},"merging-dicts","What are the ways to merge two dictionaries?","The modern way is the **`|` merge operator** (Python 3.9+), which returns a new\ndict; **`|=`** merges in place. Before 3.9, the idiom was **`{**a, **b}`\nunpacking**, and `dict.update()` merges in place.\n\n```python\na = {\"x\": 1, \"y\": 2}\nb = {\"y\": 9, \"z\": 3}\n\na | b           # {'x': 1, 'y': 9, 'z': 3}  — new dict (3.9+)\n{**a, **b}      # {'x': 1, 'y': 9, 'z': 3}  — same, works pre-3.9\n\na.update(b)     # mutates a in place -> {'x': 1, 'y': 9, 'z': 3}\n```\n\nIn every approach the **right-hand dict wins** on key collisions (`y` becomes\n`9`). Use `|` for a clean new dict on modern Python, `{**a, **b}` for\ncompatibility, and `update()`\u002F`|=` when you want to mutate in place.\n",{"id":37,"difficulty":14,"q":38,"a":39},"keys-values-items-views","What do keys(), values(), and items() return, and what is a view object?","They return **view objects** — dynamic, read-only windows onto the dict that\n**reflect changes live** rather than copying the data. They're iterable and\nsupport set-like operations, but they're not lists.\n\n```python\nd = {\"a\": 1, \"b\": 2}\nkeys = d.keys()\nd[\"c\"] = 3\nlist(keys)          # ['a', 'b', 'c'] — view updated automatically!\n\nkeys[0]             # TypeError — a view isn't indexable\nlist(d.keys())      # ['a', 'b', 'c'] — materialize when you need a list\n\nd.keys() & {\"a\"}    # {'a'} — keys views support set operations\n```\n\nBecause a view is **live**, it's memory-cheap but you must `list(...)` it to\nindex or snapshot it. Also avoid mutating the dict's size while iterating a view\n— that raises `RuntimeError`. Use views to iterate efficiently; copy to a list\nwhen you need a stable, indexable sequence.\n",{"id":41,"difficulty":14,"q":42,"a":43},"keys-hashable-lookup","Why must dictionary keys be hashable, and why are lookups O(1)?","A dict is a **hash table**: it computes `hash(key)` to decide which bucket the\nentry lives in, giving **average O(1)** insertion and lookup regardless of size.\nFor this to work, a key's hash must **never change**, so keys must be\n**hashable** — effectively **immutable**.\n\n```python\nd = {}\nd[(1, 2)] = \"ok\"     # tuple is immutable -> hashable\nd[[1, 2]] = \"no\"     # TypeError: unhashable type: 'list'\n\n# O(1): lookup time doesn't grow with the dict's size\n\"x\" in d             # hashes \"x\", checks one bucket — not a full scan\n```\n\nIf a mutable key could change after insertion, its hash would change and the\nentry would land in the wrong bucket — you'd never find it again. That's why\nlists, dicts, and sets can't be keys, but tuples and frozensets can. The\nhash-table design is exactly what makes membership tests near-instant.\n",{"id":45,"difficulty":25,"q":46,"a":47},"dict-comprehension","What is a dict comprehension?","A **dict comprehension** builds a dictionary in one expression using\n`{key: value for item in iterable}`, optionally with a filtering `if`. It's the\nconcise, readable alternative to a `for` loop that calls `d[k] = v`.\n\n```python\nsquares = {n: n * n for n in range(5)}\n# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}\n\nprices = {\"apple\": 3, \"pear\": 0, \"fig\": 7}\nin_stock = {k: v for k, v in prices.items() if v > 0}\n# {'apple': 3, 'fig': 7}\n\ninverted = {v: k for k, v in prices.items()}   # swap keys\u002Fvalues\n```\n\nLike other comprehensions it has its **own scope** (no leaked loop variable) and\nis generally faster than the equivalent loop. Use it to transform, filter, or\ninvert mappings clearly — but keep it readable rather than cramming in logic.\n",null,{"description":11},"Python interview questions on dict insertion ordering, get vs bracket access, setdefault, merging dicts, view objects, why keys must be hashable, and dict comprehensions.","python\u002Fdata-structures\u002Fdictionaries","Data Structures","data-structures","2026-06-18","LzhuhDxYYShbZNpJ1GNHVfGL3cDVdrMl9q-LhVisbXs",[57,61,64,65,69],{"subtopic":58,"path":59,"order":60},"Lists & Slicing","\u002Fpython\u002Fdata-structures\u002Flists",1,{"subtopic":62,"path":63,"order":12},"Tuples & Named Tuples","\u002Fpython\u002Fdata-structures\u002Ftuples",{"subtopic":6,"path":21,"order":20},{"subtopic":66,"path":67,"order":68},"Sets & Frozensets","\u002Fpython\u002Fdata-structures\u002Fsets",4,{"subtopic":70,"path":71,"order":72},"The collections Module","\u002Fpython\u002Fdata-structures\u002Fcollections-module",5,{"path":74,"title":75},"\u002Fblog\u002Fpython-dictionaries-explained","Python Dictionaries Explained — Ordering, Lookups, and Merging",1781808676429]