{"id":535,"date":"2026-01-20T18:57:14","date_gmt":"2026-01-20T18:57:14","guid":{"rendered":"http:\/\/askpython.com\/?p=535"},"modified":"2026-01-25T15:03:46","modified_gmt":"2026-01-25T15:03:46","slug":"python-dictionary-dict-tutorial","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python\/dictionary\/python-dictionary-dict-tutorial","title":{"rendered":"Python Dictionary (Dict) Tutorial"},"content":{"rendered":"<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nuser = {&quot;name&quot;: &quot;Alice&quot;, &quot;age&quot;: 30, &quot;role&quot;: &quot;developer&quot;}\nprint(user&#x5B;&quot;name&quot;])  # Alice\n\n<\/pre><\/div>\n\n\n<p>That&#8217;s a Python dictionary. Key-value pairs wrapped in curly braces, and you&#8217;re done.<\/p>\n\n\n\n<p>If you&#8217;ve been programming for more than five minutes, you&#8217;ve probably used a dictionary without realizing it. They&#8217;re everywhere because they solve a fundamental problem: computers are great at remembering things, but only if you label them properly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating Python dictionaries from scratch<\/h2>\n\n\n\n<p>The basic syntax gives you three ways to create a dict. Pick whichever feels right for the situation.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Method 1: Literal notation\nperson = {&quot;first&quot;: &quot;John&quot;, &quot;last&quot;: &quot;Doe&quot;, &quot;age&quot;: 28}\n\n# Method 2: dict() constructor\nperson = dict(first=&quot;John&quot;, last=&quot;Doe&quot;, age=28)\n\n# Method 3: Empty dict you&#039;ll populate later\nperson = {}\nperson&#x5B;&quot;first&quot;] = &quot;John&quot;\nperson&#x5B;&quot;last&quot;] = &quot;Doe&quot;\nperson&#x5B;&quot;age&quot;] = 28\n\n<\/pre><\/div>\n\n\n<p>All three produce identical results. The literal notation (method 1) is faster and more common in production code. The constructor (method 2) looks cleaner when you&#8217;re passing values as function arguments. The empty dict approach (method 3) makes sense when you&#8217;re building data iteratively.<\/p>\n\n\n\n<p>Keys can be strings, numbers, or tuples (anything immutable, really). Values can be absolutely anything.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nmixed = {\n    &quot;string_key&quot;: &quot;value&quot;,\n    42: &quot;numeric key&quot;,\n    (1, 2): &quot;tuple key&quot;,\n    &quot;nested&quot;: {&quot;another&quot;: &quot;dict&quot;}\n}\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Accessing dictionary values in Python<\/h2>\n\n\n\n<p>You&#8217;ve got two options here, and they behave differently when keys don&#8217;t exist.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nconfig = {&quot;debug&quot;: True, &quot;port&quot;: 8080}\n\n# Square bracket notation\nprint(config&#x5B;&quot;debug&quot;])  # True\nprint(config&#x5B;&quot;missing&quot;])  # KeyError: &#039;missing&#039;\n\n# get() method\nprint(config.get(&quot;debug&quot;))  # True\nprint(config.get(&quot;missing&quot;))  # None\nprint(config.get(&quot;missing&quot;, &quot;default&quot;))  # &#039;default&#039;\n\n<\/pre><\/div>\n\n\n<p>The square bracket approach crashes hard when the key doesn&#8217;t exist. Sometimes that&#8217;s what you want (fail fast). The get() method returns None by default or whatever fallback value you specify. I use get() constantly in production because it prevents defensive coding nonsense.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Modifying dictionary data in Python<\/h2>\n\n\n\n<p>Dictionaries are mutable, which means you can change them after creation. This is either convenient or dangerous depending on your perspective.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nsettings = {&quot;theme&quot;: &quot;dark&quot;, &quot;lang&quot;: &quot;en&quot;}\n\n# Add new key-value pair\nsettings&#x5B;&quot;notifications&quot;] = True\n\n# Update existing value\nsettings&#x5B;&quot;theme&quot;] = &quot;light&quot;\n\n# Update multiple values\nsettings.update({&quot;lang&quot;: &quot;es&quot;, &quot;timezone&quot;: &quot;UTC&quot;})\n\nprint(settings)\n# {&#039;theme&#039;: &#039;light&#039;, &#039;lang&#039;: &#039;es&#039;, &#039;notifications&#039;: True, &#039;timezone&#039;: &#039;UTC&#039;}\n\n<\/pre><\/div>\n\n\n<p>The update() method merges another dictionary into the existing one. Any overlapping keys get overwritten. Any new keys get added.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Removing items from Python dictionaries<\/h2>\n\n\n\n<p>Four different ways to delete things, each with different behavior.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndata = {&quot;a&quot;: 1, &quot;b&quot;: 2, &quot;c&quot;: 3}\n\n# pop() removes and returns the value\nvalue = data.pop(&quot;a&quot;)  # Returns 1\nvalue = data.pop(&quot;missing&quot;, &quot;not found&quot;)  # Returns &quot;not found&quot;\n\n# del keyword removes by key\ndel data&#x5B;&quot;b&quot;]\n\n# popitem() removes and returns the last item (Python 3.7+)\nitem = data.popitem()  # Returns (&#039;c&#039;, 3)\n\n# clear() nukes everything\ndata.clear()  # {}\n\n<\/pre><\/div>\n\n\n<p>I almost always use pop() because it handles missing keys gracefully with a default value. The del keyword is fine for quick scripts. Avoid popitem() unless you specifically need LIFO behavior.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Looping through Python dictionaries<\/h2>\n\n\n\n<p>Dictionaries give you three ways to iterate, depending on whether you need keys, values, or both.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nscores = {&quot;alice&quot;: 95, &quot;bob&quot;: 87, &quot;charlie&quot;: 92}\n\n# Iterate over keys (default behavior)\nfor name in scores:\n    print(name)\n\n# Iterate over values\nfor score in scores.values():\n    print(score)\n\n# Iterate over key-value pairs\nfor name, score in scores.items():\n    print(f&quot;{name} scored {score}&quot;)\n\n<\/pre><\/div>\n\n\n<p>The items() method is what you want 90% of the time. It unpacks each key-value pair into separate variables, making your code way more readable than scores[name] everywhere.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dictionary comprehensions in Python<\/h2>\n\n\n\n<p>List comprehensions are great. Dictionary comprehensions are the same idea but for dicts.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Create dict from sequence\nnumbers = &#x5B;1, 2, 3, 4, 5]\nsquares = {n: n**2 for n in numbers}\n# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}\n\n# Filter while building\nevens = {n: n**2 for n in numbers if n % 2 == 0}\n# {2: 4, 4: 16}\n\n# Transform existing dict\nprices = {&quot;apple&quot;: 1.2, &quot;banana&quot;: 0.5, &quot;orange&quot;: 0.8}\nrounded = {k: round(v) for k, v in prices.items()}\n# {&#039;apple&#039;: 1, &#039;banana&#039;: 0, &#039;orange&#039;: 1}\n\n<\/pre><\/div>\n\n\n<p>Comprehensions run faster than loops because they&#8217;re optimized at the bytecode level. They also force you to think declaratively, which usually results in cleaner code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checking if keys exist in Python dictionaries<\/h2>\n\n\n\n<p>Three approaches, each with different performance characteristics.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nuser = {&quot;name&quot;: &quot;Alice&quot;, &quot;email&quot;: &quot;alice@example.com&quot;}\n\n# in operator (fastest)\nif &quot;name&quot; in user:\n    print(&quot;Name exists&quot;)\n\n# get() with default\nemail = user.get(&quot;email&quot;, &quot;no-email@example.com&quot;)\n\n# keys() method (unnecessary, avoid)\nif &quot;name&quot; in user.keys():  # Don&#039;t do this\n    print(&quot;Slower than necessary&quot;)\n\n<\/pre><\/div>\n\n\n<p>The <code>in<\/code> operator checks membership directly on the hash table. It&#8217;s fast and readable. Using user.keys() adds an extra method call for zero benefit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Python dictionary methods you&#8217;ll actually use<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndata = {&quot;x&quot;: 10, &quot;y&quot;: 20}\n\n# Get all keys\nkeys = data.keys()  # dict_keys(&#x5B;&#039;x&#039;, &#039;y&#039;])\n\n# Get all values\nvalues = data.values()  # dict_values(&#x5B;10, 20])\n\n# Get all items\nitems = data.items()  # dict_items(&#x5B;(&#039;x&#039;, 10), (&#039;y&#039;, 20)])\n\n# setdefault() adds key only if missing\ndata.setdefault(&quot;z&quot;, 30)  # Adds z: 30\ndata.setdefault(&quot;x&quot;, 99)  # Leaves x: 10 unchanged\n\n<\/pre><\/div>\n\n\n<p>The setdefault() method is weirdly useful for building nested structures without checking existence every time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Merging dictionaries in Python<\/h2>\n\n\n\n<p>Python 3.9 added the merge operator, which is cleaner than anything that came before.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndefaults = {&quot;color&quot;: &quot;blue&quot;, &quot;size&quot;: &quot;medium&quot;}\ncustom = {&quot;size&quot;: &quot;large&quot;, &quot;material&quot;: &quot;cotton&quot;}\n\n# Merge operator (Python 3.9+)\nfinal = defaults | custom\n# {&#039;color&#039;: &#039;blue&#039;, &#039;size&#039;: &#039;large&#039;, &#039;material&#039;: &#039;cotton&#039;}\n\n# Old way (still works)\nfinal = {**defaults, **custom}\n\n# In-place update\ndefaults |= custom  # Modifies defaults directly\n\n<\/pre><\/div>\n\n\n<p>Values from the right side override the left. Simple as that.<\/p>\n\n\n\n<p>Dictionaries are fast because they use hash tables underneath. Lookup time is O(1) on average, meaning it takes the same time whether you have 10 items or 10 million. That&#8217;s why you see them everywhere in Python code, from argument parsing to caching to configuration management.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>That&#8217;s a Python dictionary. Key-value pairs wrapped in curly braces, and you&#8217;re done. If you&#8217;ve been programming for more than five minutes, you&#8217;ve probably used a dictionary without realizing it. They&#8217;re everywhere because they solve a fundamental problem: computers are great at remembering things, but only if you label them properly. Creating Python dictionaries from [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":65748,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-535","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dictionary"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=535"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/535\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/65748"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}