BASIC Python (Beginner Level) 📂 Basic Python Programming · 10 of 15 235 min read

Python Dictionaries — Keys, Values, Hashing

Master Python dictionaries from the ground up. This tutorial explains keys and values, how dicts are stored in memory as hash tables (with animated diagrams), what hashing is and why it makes lookups O(1), which keys are valid (hashable) and which are not, safe access with get() and setdefault(), all dictionary methods (keys, values, items, update, pop, etc.), for-loop patterns, dict comprehensions, nested dictionaries, and a full word-frequency practice program.

🌐
SectionSection第 01 节

The Story That Explains Dictionaries 🗂️Dictionaries समझाने वाली कहानी 🗂️一个解释字典的故事 🗂️

The Old Library Card Catalogueपुराने पुस्तकालय की Card सूची老图书馆的卡片目录
Picture a library before computers. You want Godaan by Premchand. You could walk every aisle reading spines — thousands of books, one by one. Or you could go to the card catalogue: a cabinet of drawers, each labelled with letters. You open the "P" drawer, flip to Premchand, and the card tells you exactly which shelf the book is on. It takes seconds, however big the library is.

A Python dictionary is that card catalogue. You give it a key (a title, a name, a coordinate) and it hands back the value almost instantly — no scanning. The trick behind it is called hashing: Python turns the key into a number that says which "drawer" holds the value.

Dictionaries are among Python's most useful built-in types. JSON data, settings, counters, caches and even the attributes of your own objects are stored in dicts.
कंप्यूटर से पहले का एक पुस्तकालय सोचिए। आपको प्रेमचंद की गोदान चाहिए। आप हर गलियारे में किताबों की पीठ पढ़ते हुए चल सकते हैं — हज़ारों किताबें, एक-एक करके। या आप card सूची पर जा सकते हैं: दराज़ों वाली अलमारी, हर दराज़ पर अक्षर लिखे हैं। आप "P" वाली दराज़ खोलते हैं, Premchand तक पलटते हैं, और card ठीक बताता है कि किताब किस शेल्फ़ पर है। पुस्तकालय कितना भी बड़ा हो, कुछ सेकंड लगते हैं।

Python की dictionary वही card सूची है। आप उसे एक key (शीर्षक, नाम, coordinate) देते हैं और वह लगभग तुरंत value लौटा देती है — बिना छाने। इसके पीछे की तरकीब है hashing: Python key को एक संख्या में बदलता है जो बताती है कि value किस "दराज़" में है।

Dictionaries Python के सबसे काम के built-in types में हैं। JSON data, settings, गिनती, cache, और आपके अपने objects के attributes भी dicts में रखे जाते हैं।
想象一下没有电脑时的图书馆。你想找普列姆昌德的《戈丹》。你可以走遍每条过道逐本查看书脊 —— 成千上万本书,一本一本看。或者你去卡片目录:一个装满抽屉的柜子,每个抽屉都标着字母。你拉开 "P" 抽屉,翻到 Premchand,卡片会准确告诉你书在哪个书架上。无论图书馆多大,只需几秒钟。

Python 的字典就是这个卡片目录。你给它一个键(书名、人名、坐标),它几乎立刻返回值 —— 不用逐个扫描。背后的技巧叫哈希:Python 把键变成一个数字,这个数字指明值放在哪个“抽屉”里。

字典是 Python 最有用的内置类型之一。JSON 数据、配置、计数器、缓存,甚至你自己定义的对象的属性,都存放在字典里。

A dictionary (dict) is Python's built-in mapping type — a collection of key-value pairs where every key is unique. You look things up by key, not by position, and a lookup takes about the same time on average whether the dict has 10 items or 10 million (computer scientists write this as O(1)).

Dictionary (dict) Python का built-in mapping type है — key-value जोड़ियों का संग्रह जिसमें हर key अनोखी है। आप जगह से नहीं, key से ढूँढते हैं, और dict में 10 items हों या 1 करोड़, lookup में औसतन लगभग उतना ही समय लगता है (computer scientists इसे O(1) लिखते हैं)।

字典(dict)是 Python 内置的映射类型 —— 由键值对组成的集合,每个键都是唯一的。你按键而不是按位置查找;无论字典有 10 项还是 1000 万项,查找的平均耗时几乎相同(计算机科学家把它写作 O(1))。

🔐
Key → ValueKey → Value键 → 值
the mapping modelmapping का ढाँचा映射模型
Each entry has two parts. The key is the unique label you look up by. The value is whatever data belongs to that key — anything Python can hold.
हर entry के दो हिस्से हैं। Key वह अनोखा label है जिससे आप ढूँढते हैं। Value उस key का data है — Python जो कुछ भी रख सके।
每个条目有两部分。键是用来查找的唯一标签;值是属于该键的数据 —— Python 能存放的任何东西。
🆔
Unique Keysअनोखी Keys键唯一
one value per keyहर key का एक मान每个键一个值
No two entries can share a key. Assigning to an existing key replaces its value. Need several values for one key? Store a list as the value.
दो entries की key एक नहीं हो सकती। मौजूदा key पर assign करने से उसका मान बदल जाता है। एक key के कई मान चाहिए? मान के रूप में list रखें।
两个条目不能共用一个键。给已有的键赋值会替换它的值。一个键需要多个值?把列表作为值。
⚡
Fast Lookupतेज़ Lookup快速查找
O(1) on averageऔसतन O(1)平均 O(1)
Finding a value does not get slower as the dict grows. That is only possible because of hashing, which you will see step by step below.
Dict बड़ी होने पर भी मान ढूँढना धीमा नहीं होता। यह सिर्फ़ hashing से संभव है, जिसे आप नीचे क़दम-दर-क़दम देखेंगे।
字典变大,查找也不会变慢。这完全归功于哈希,下面会一步步展示。
▶️
This Tutorial Has Six Simulatorsइस Tutorial में छह Simulators हैं本教程有六个模拟器

Look for the live boxes: the Hash Table Simulator (Section 05), the Key Rules Checker (06), the Key-Value Lab (07), the Dict Method Simulator (08), the Loop Pattern Stepper (09) and the Nested Dict Explorer (10). Type your own keys and values, press the buttons and watch each step. They follow real Python rules, errors included.

Live boxes देखें: Hash Table Simulator (Section 05), Key Rules Checker (06), Key-Value Lab (07), Dict Method Simulator (08), Loop Pattern Stepper (09) और Nested Dict Explorer (10)। अपनी keys और मान लिखें, buttons दबाएँ और हर क़दम देखें। ये असली Python के नियम मानते हैं, errors समेत।

留意这些互动框:哈希表模拟器(第 05 节)、键规则检查器(06)、键值实验室(07)、字典方法模拟器(08)、循环模式单步器(09)和嵌套字典探索器(10)。输入你自己的键和值,按下按钮,观察每一步。它们遵循真实的 Python 规则,包括报错。


SectionSection第 02 节

Keys and Values — The Basic Structure 🔑Keys और Values — बुनियादी ढाँचा 🔑键与值 —— 基本结构 🔑

Every entry is a key-value pair: two objects joined by a colon :. The key is what you ask for; the value is what you get back. Pairs sit inside curly braces {}, separated by commas.

हर entry एक key-value जोड़ी है: colon : से जुड़े दो objects। Key वह है जो आप माँगते हैं; value वह जो आपको मिलती है। जोड़ियाँ curly braces {} के अंदर commas से अलग रहती हैं।

每个条目都是一个键值对:由冒号 : 连接的两个对象。键是你要查的,值是你得到的。键值对放在花括号 {} 里,用逗号分隔。

🔑 Three key-value pairs🔑 तीन key-value जोड़ियाँ🔑 三个键值对
Dictionary key-value structureuser = {"name": "Asha", "age": 30, "city": "Pune"}"name""Asha""age"30"city""Pune"KEYS (unique, hashable)KEYS (अनोखी, hashable)键(唯一、可哈希)VALUES (anything)VALUES (कुछ भी)值(任意)

Each key maps to one value. The order you insert them is kept (Python 3.7+).

हर key एक मान से जुड़ी है। डालने का क्रम बना रहता है (Python 3.7+)।

每个键对应一个值。插入顺序会被保留(Python 3.7+)。

user = {
    "name": "Asha",
    "age": 30,
    "city": "Pune",
}
print(user["name"], user["age"])

mixed = {
    "name": "Ravi",        # str key
    42: "answer",          # int key
    (1, 2): "point",       # tuple key — allowed!
    None: "nothing",       # None key
}
print(mixed[42], mixed[(1, 2)], mixed[None])

inventory = {
    "apples": 12,                  # int value
    "scores": [88, 92, 75],        # list value
    "config": {"tax": 0.18},       # dict value
    "active": True,                # bool value
}
print(inventory["scores"], inventory["config"]["tax"])   # nested access
print(len(user), list(user))       # 3 pairs; a dict lists its keys in insertion order
OUTPUT
Asha 30 answer point nothing [88, 92, 75] 0.18 3 ['name', 'age', 'city']
💡
Since Python 3.7 — Insertion Order Is KeptPython 3.7 से — डालने का क्रम बना रहता है从 Python 3.7 起 —— 保持插入顺序

A dict remembers the order you added keys. Looping gives the keys in that order, as list(user) shows above. (CPython 3.6 already did this, but it became an official language rule only in 3.7.) Old tutorials that call dicts "unordered" are out of date.

Dict याद रखती है कि आपने keys किस क्रम में डालीं। Loop उसी क्रम में keys देता है, जैसा ऊपर list(user) दिखाता है। (CPython 3.6 पहले से ऐसा करता था, पर 3.7 में यह भाषा का आधिकारिक नियम बना।) Dicts को "unordered" कहने वाले पुराने tutorials पुराने पड़ चुके हैं।

字典会记住你添加键的顺序。遍历时按这个顺序给出键,如上面的 list(user) 所示。(CPython 3.6 已经这样做了,但到 3.7 才成为正式的语言规则。)说字典“无序”的旧教程已经过时了。


SectionSection第 03 节

Creating Dictionaries — Five Ways ✍️Dictionaries बनाना — पाँच तरीक़े ✍️创建字典 —— 五种方式 ✍️

empty  = {}
prices = {"apple": 1.2, "bread": 3.5, "milk": 2.8}

user = dict(name="Asha", age=30, city="Pune")      # keyword args → str keys
pairs = [("a", 1), ("b", 2), ("c", 3)]
from_pairs = dict(pairs)                          # from (key, value) pairs
zeroed = dict.fromkeys(["x", "y", "z"], 0)        # same value for many keys
squares = {n: n ** 2 for n in range(1, 6)}        # dict comprehension

print(empty, prices)
print(user)
print(from_pairs, zeroed)
print(squares)
print(type({}).__name__, type(set()).__name__)    # {} is a DICT; use set() for an empty set
print(dict(zip(["a", "b"], [1, 2])))              # zip two lists into a dict
OUTPUT
{} {'apple': 1.2, 'bread': 3.5, 'milk': 2.8} {'name': 'Asha', 'age': 30, 'city': 'Pune'} {'a': 1, 'b': 2, 'c': 3} {'x': 0, 'y': 0, 'z': 0} {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} dict set {'a': 1, 'b': 2}
⚠️
Two Small Trapsदो छोटे जाल两个小陷阱

1. {} is an empty dict, not an empty set — use set() for that.
2. dict(name="Asha") only works when every key is a text that is also a valid Python name. For keys like "first name" or 42, use braces.

1. {} ख़ाली dict है, ख़ाली set नहीं — उसके लिए set() लगाएँ।
2. dict(name="Asha") तभी चलता है जब हर key ऐसा text हो जो Python का सही नाम भी हो। "first name" या 42 जैसी keys के लिए braces लगाएँ।

1. {} 是空字典,不是空集合 —— 空集合要用 set()。
2. dict(name="Asha") 只有在每个键都是合法 Python 名字的文本时才能用。像 "first name" 或 42 这样的键,请用花括号。


SectionSection第 04 节

What Is Hashing? — The Core Idea #️⃣Hashing क्या है? — मूल विचार #️⃣什么是哈希?—— 核心思想 #️⃣

The Cloakroom TokenCloakroom का टोकन衣帽间的号牌
You leave your bag at a cloakroom. The attendant does not remember faces — that would be slow. She hangs the bag on a numbered hook and gives you a token with that number. When you return, she reads the number and walks straight to that hook. She never searches; she just reads a number.

That is hashing. A hash function takes an object (your bag = a key like "Asha") and produces a whole number (the token = the hash). Python uses that number to calculate where the value is kept.
आप cloakroom में अपना बैग छोड़ते हैं। वहाँ का कर्मचारी चेहरे याद नहीं रखता — वह धीमा होगा। वह बैग एक नंबर वाली खूँटी पर टाँगता है और आपको उस नंबर का टोकन देता है। लौटने पर वह नंबर पढ़ता है और सीधे उस खूँटी पर जाता है। वह कभी खोजता नहीं; बस नंबर पढ़ता है।

यही hashing है। Hash function एक object (आपका बैग = "Asha" जैसी key) लेकर एक पूर्ण संख्या (टोकन = hash) बनाता है। Python उस संख्या से गणना करता है कि मान कहाँ रखा है।
你把包寄存在衣帽间。服务员不记长相 —— 那样太慢。她把包挂在一个编了号的挂钩上,给你一个写着这个号码的号牌。你回来时,她看一眼号码,直接走到那个挂钩前。她从不搜索,只是读一个数字。

这就是哈希。哈希函数接收一个对象(你的包 = 像 "Asha" 这样的键),产生一个整数(号牌 = 哈希值)。Python 用这个数字计算出值存放的位置。
#️⃣ From key to slot#️⃣ Key से slot तक#️⃣ 从键到槽位
From key to slot"Ravi"KEYKEY键hash()HASH FUNCTIONHASH FUNCTION哈希函数402HASH (toy: 82+97+118+105)HASH (खिलौना: 82+97+118+105)哈希(玩具:82+97+118+105)& 72SLOT (of 8)SLOT (8 में से)槽位(共 8 个)1. Same key → always the same hash (while the program runs)1. वही key → हमेशा वही hash (program चलते समय)1. 同一个键 → 总是同一个哈希(程序运行期间)2. Different keys → spread out over the slots2. अलग keys → slots में फैल जाती हैं2. 不同的键 → 均匀分散到各槽位

Real str hashes are huge random-looking numbers; this picture uses the same toy hash as the simulator below.

असली str hashes बड़ी, बेतरतीब-सी संख्याएँ हैं; यह चित्र नीचे के simulator वाला ही खिलौना hash लेता है।

真实的字符串哈希是看似随机的大数;这张图使用与下面模拟器相同的玩具哈希。

Python's built-in hash() works on any hashable object — in practice, the built-in immutable types and tuples made of them.

Python का built-in hash() किसी भी hashable object पर चलता है — व्यवहार में, built-in immutable types और उनसे बने tuples।

Python 内置的 hash() 适用于任何可哈希对象 —— 实际上就是内置的不可变类型以及由它们组成的元组。

print(hash(42), hash(-1), hash(True), hash(1.0))  # ints hash to themselves (except -1)
print(hash(3.14))
print(hash((1, 2, 3)))                            # tuples of hashables hash too
print(hash("Asha") == hash("Asha"))               # same key → same hash, always
print(hash("Asha") == hash("Ravi"))               # different keys → almost always different

for bad in ([1, 2, 3], {"a": 1}, {1, 2, 3}):
    try:
        hash(bad)
    except TypeError as err:
        print("TypeError:", err)
OUTPUT
42 -2 1 1 322818021289917443 529344067295497451 True False TypeError: unhashable type: 'list' TypeError: unhashable type: 'dict' TypeError: unhashable type: 'set'
# Run this file twice: the str hashes change each time Python starts (hash randomization).
print(hash("Asha"), hash("Ravi"))
OUTPUT — THE SAME FILE RUN TWICEOUTPUT — वही file दो बार चलाईOUTPUT —— 同一个文件运行两次
Run 1: 3931773391350678776 -3201546630201516209 Run 2: -7912673852280061647 -537046682806702867
🎲
Why String Hashes Change Between RunsString hashes हर run में क्यों बदलते हैं为什么字符串哈希每次运行都不同

For security, Python mixes a random secret into string hashes each time it starts (hash randomisation). This stops attackers from crafting many keys that all collide and slow a server down. Within one run the hash never changes, which is all a dict needs. Number hashes are not randomised: hash(42) is always 42.

सुरक्षा के लिए Python हर बार शुरू होने पर string hashes में एक बेतरतीब गुप्त मान मिलाता है (hash randomisation)। इससे हमलावर ऐसी बहुत सी keys नहीं बना पाते जो सब टकराकर server को धीमा कर दें। एक run के अंदर hash कभी नहीं बदलता, और dict को बस इतना ही चाहिए। संख्याओं के hash बेतरतीब नहीं होते: hash(42) हमेशा 42 है।

出于安全考虑,Python 每次启动时都会往字符串哈希里混入一个随机秘密值(哈希随机化)。这能防止攻击者构造大量相互冲突的键来拖慢服务器。在一次运行中哈希值永远不变,而这正是字典所需要的。数字的哈希不会随机化:hash(42) 永远是 42。


SectionSection第 05 节

How Dictionaries Are Stored in Memory 🧠Dictionaries Memory में कैसे रहती हैं 🧠字典如何存储在内存中 🧠

A dict is a hash table. Since Python 3.6, CPython uses a "compact" design with two parts: a small index table of slots, and an entries list that stores (hash, key, value) in insertion order. To run d["Ravi"] = 25, Python:

Dict एक hash table है। Python 3.6 से CPython दो हिस्सों वाला "compact" design लगाता है: slots की एक छोटी index table, और एक entries list जो (hash, key, value) डालने के क्रम में रखती है। d["Ravi"] = 25 चलाने के लिए Python:

字典是一张哈希表。从 Python 3.6 起,CPython 采用由两部分组成的“紧凑”设计:一张由槽位组成的小索引表,以及一个按插入顺序存放 (哈希, 键, 值) 的条目列表。执行 d["Ravi"] = 25 时,Python 会:

01
Compute the hashHash निकालें计算哈希
hash("Ravi") → a big integer.
hash("Ravi") → एक बड़ा integer।
hash("Ravi") → 一个大整数。
02
Pick a slotSlot चुनें选择槽位
Keep the last bits: hash & (size − 1), which equals hash % size for a power-of-two size.
आख़िरी bits रखें: hash & (size − 1), जो 2 की घात वाले size के लिए hash % size के बराबर है।
保留最低几位:hash & (size − 1),当 size 是 2 的幂时等于 hash % size。
03
Handle a collisionटकराव संभालें处理冲突
If the slot is taken by a different key, follow a fixed probe sequence to another slot.
अगर slot में कोई दूसरी key है, तो एक तय probe क्रम से दूसरे slot पर जाएँ।
如果槽位已被其他键占用,就沿着固定的探测序列去另一个槽位。
04
Store the entryEntry रखें存入条目
Append (hash, key, value) to the entries list; the slot remembers its position.
(hash, key, value) को entries list के अंत में जोड़ें; slot उसकी जगह याद रखता है।
把 (哈希, 键, 值) 追加到条目列表;槽位记住它的位置。
05
To read: repeat steps 1–3, then fetchपढ़ने के लिए: क़दम 1–3 दोहराएँ, फिर निकालें读取:重复第 1–3 步,然后取值
Same key → same hash → same slot → the value. O(1) on average.
वही key → वही hash → वही slot → मान। औसतन O(1)।
同一个键 → 同一个哈希 → 同一个槽位 → 取到值。平均 O(1)。

The Hash Table in MemoryMemory में Hash Table内存中的哈希表

🗄️ Index table + entries🗄️ Index table + entries🗄️ 索引表 + 条目
A compact dict: index table plus entriesuser = {"Asha": 30, "Ravi": 25, "Meena": 35}INDEX TABLE — 8 slots (toy hash & 7)INDEX TABLE — 8 slots (खिलौना hash & 7)索引表 —— 8 个槽位(玩具哈希 & 7)[0]·[1]·[2]#1[3]·[4]·[5]#0[6]#2[7]·ENTRIES — in insertion orderENTRIES — डालने के क्रम में条目 —— 按插入顺序#0hash 381"Asha"30#1hash 402"Ravi"25#2hash 486"Meena"35Looking up "Ravi": hash 402 → 402 & 7 = 2 → slot [2] says #1 → value 25"Ravi" ढूँढना: hash 402 → 402 & 7 = 2 → slot [2] कहता है #1 → मान 25查找 "Ravi":哈希 402 → 402 & 7 = 2 → 槽位 [2] 指向 #1 → 值 25One hash, one slot, one entry: the work does not depend on the size of the dict.एक hash, एक slot, एक entry: काम dict के आकार पर निर्भर नहीं करता।一次哈希、一个槽位、一个条目:工作量与字典大小无关。

Toy hashes (sum of letter codes) are used so you can check the maths; the layout is the real CPython one.

खिलौना hashes (अक्षर-कोड का जोड़) लिए गए हैं ताकि आप गणित जाँच सकें; बनावट असली CPython वाली है।

这里用玩具哈希(字符编码之和)方便你核对计算;布局是 CPython 的真实布局。

What About Collisions?टकराव (Collisions) का क्या?冲突怎么办?

Two different keys can land on the same slot. CPython uses open addressing: it moves to another slot and checks again. It does not simply step to the next slot; it follows a pseudo-random sequence slot = (5 × slot + 1 + perturb) & mask, where perturb brings in more bits of the hash each round. With the toy hash, 'ab' and 'ba' both have hash 195, so they collide at slot 3:

दो अलग keys एक ही slot पर आ सकती हैं। CPython open addressing लगाता है: वह दूसरे slot पर जाकर फिर जाँचता है। वह बस अगले slot पर नहीं जाता; वह एक pseudo-random क्रम मानता है slot = (5 × slot + 1 + perturb) & mask, जहाँ perturb हर बार hash के और bits लाता है। खिलौना hash में 'ab' और 'ba' दोनों का hash 195 है, इसलिए वे slot 3 पर टकराते हैं:

两个不同的键可能落到同一个槽位。CPython 使用开放寻址:换到另一个槽位再检查。它不是简单地走到下一个槽位,而是遵循一个伪随机序列 slot = (5 × slot + 1 + perturb) & mask,其中 perturb 每轮引入哈希的更多位。用玩具哈希时,'ab' 和 'ba' 的哈希都是 195,所以它们在槽位 3 冲突:

💥 'ab' and 'ba' collide💥 'ab' और 'ba' टकराते हैं💥 'ab' 与 'ba' 冲突
Hash collision and probing[0][1][2][3]'ab'[4][5][6]'ba'[7](5×3 + 1 + 6) & 7 = 6'ba' finds slot 3 taken, probes, and lands in slot 6'ba' को slot 3 भरा मिलता है, वह probe करके slot 6 पर पहुँचता है'ba' 发现槽位 3 被占,探测后落到槽位 6
💡
Why Keep the Table Partly Empty?Table को कुछ ख़ाली क्यों रखें?为什么让表保持部分空闲?

A crowded table means many collisions and long probe chains. So CPython lets a table fill only about 2/3 of its slots. An 8-slot table holds 5 entries; the 6th insert triggers a resize to a bigger power of two (about 3 × the number of keys), and every key is re-inserted. The real sizes below show these jumps at 1, 6, 11 and 22 items.

भरी हुई table में बहुत टकराव और लंबी probe लड़ियाँ होती हैं। इसलिए CPython table के सिर्फ़ लगभग 2/3 slots भरने देता है। 8 slots वाली table 5 entries रखती है; 6वीं डालने पर 2 की बड़ी घात (keys की संख्या का लगभग 3 गुना) में resize होता है, और हर key दोबारा डाली जाती है। नीचे के असली आकार 1, 6, 11 और 22 items पर ये उछाल दिखाते हैं।

表太满会导致大量冲突和很长的探测链。所以 CPython 只让表填满约 2/3 的槽位。8 槽的表最多放 5 个条目;插入第 6 个时触发扩容,变成更大的 2 的幂(约为键数的 3 倍),并重新插入所有键。下面的真实大小显示了在 1、6、11、22 项时的跳变。

import sys
d = {}
last = sys.getsizeof(d)
print(f"empty dict: {last} bytes")
for i in range(25):
    d[i] = i
    size = sys.getsizeof(d)
    if size != last:                 # the hash table just grew
        print(f"after {len(d):>2} items: {size} bytes")
        last = size
OUTPUT
empty dict: 64 bytes after 1 items: 224 bytes after 6 items: 352 bytes after 11 items: 632 bytes after 22 items: 1168 bytes

Try It — Hash Table Simulatorआज़माएँ — Hash Table Simulator动手试试 —— 哈希表模拟器

Type a key, press Insert, and watch it travel: hash → slot → store. The presets show a collision, a deleted slot (DUMMY) and a resize. The left side is the real CPython layout: an index table of slots plus an entries list in insertion order.

कोई key लिखें, Insert दबाएँ, और उसका सफ़र देखें: hash → slot → store। Presets टकराव, मिटाया गया slot (DUMMY) और resize दिखाते हैं। बाईं ओर असली CPython बनावट है: slots की index table और डालने के क्रम वाली entries list।

输入一个键,点击插入,观察它的旅程:哈希 → 槽位 → 存入。预设展示了冲突、已删除槽位(DUMMY)和扩容。左边是 CPython 的真实布局:由槽位组成的索引表,加上按插入顺序排列的条目列表。

🗄️ Hash Table SimulatorHash Table Simulator哈希表模拟器hash → slot → store. Collisions, DUMMY slots and resizing.hash → slot → store। टकराव, DUMMY slots और resize।哈希 → 槽位 → 存入。冲突、DUMMY 槽位与扩容。
Presets:Presets:预设:
index table (slots)index table (slots)索引表(槽位)
entries (insertion order)entries (डालने का क्रम)条目(插入顺序)
💡
About the Toy String Hashखिलौना String Hash के बारे में关于玩具字符串哈希

Real hash("Asha") is a huge number that changes every time Python starts. So the simulator uses a simple made-up hash for strings: the sum of the letter codes. Int keys use the real Python hash. The slot maths, the probe order, the DUMMY markers and the 2/3 resize rule follow CPython.

असली hash("Asha") एक बहुत बड़ी संख्या है जो हर बार Python शुरू होने पर बदलती है। इसलिए simulator strings के लिए एक सरल बनाया हुआ hash लेता है: अक्षर-कोड का जोड़। Int keys असली Python hash लेती हैं। Slot का गणित, probe क्रम, DUMMY निशान और 2/3 resize नियम CPython जैसे हैं।

真实的 hash("Asha") 是一个巨大的数,每次启动 Python 都会变。所以模拟器对字符串使用一个简单的自制哈希:字符编码之和。整数键使用真实的 Python 哈希。槽位计算、探测顺序、DUMMY 标记和 2/3 扩容规则都与 CPython 一致。


SectionSection第 06 节

Rules for Valid Dictionary Keys 🔐सही Dictionary Keys के नियम 🔐合法字典键的规则 🔐

A key must be hashable: its hash must never change while it sits in the dict. For built-in types this means immutable — if a key could change, its hash would change, and Python would look in the wrong slot.

Key hashable होनी चाहिए: dict में रहते हुए उसका hash कभी नहीं बदलना चाहिए। Built-in types के लिए इसका मतलब है immutable — अगर key बदल सके तो उसका hash बदलेगा, और Python ग़लत slot में देखेगा।

键必须是可哈希的:它在字典中时哈希值绝不能改变。对内置类型来说,这意味着不可变 —— 如果键能改变,它的哈希也会变,Python 就会去错误的槽位查找。

❌ Invalid keys (unhashable)ग़लत keys (unhashable)非法的键(不可哈希)
TypeType类型Exampleउदाहरण示例
list[1, 2, 3]
dict{"a": 1}
set{1, 2, 3}
tuple holding a listlist वाला tuple含列表的元组(1, [2, 3])
bytearraybytearray(b"hi")
✅ Valid keys (hashable)सही keys (hashable)合法的键(可哈希)
TypeType类型Exampleउदाहरण示例
int / float / bool42, 3.14, True
str"name"
tuple of hashableshashables का tuple由可哈希项组成的元组(1, 2)
frozensetfrozenset({1, 2})
NoneNone
d = {}
d[42]     = "int key"
d["name"] = "str key"
d[3.14]   = "float key"
d[(1, 2)] = "tuple key"        # great for coordinates
d[None]   = "None as key"
print(d[(1, 2)], len(d))

for bad in ("[1, 2]", '{"a": 1}', "{1, 2}", "(1, [2])"):
    try:
        d[eval(bad)] = "x"
    except TypeError as err:
        print(f"d[{bad}] → TypeError: {err}")

same = {}
same[1] = "int"
same[1.0] = "float"            # 1.0 == 1 and same hash → SAME key
same[True] = "bool"            # True == 1 too!
print(same)                    # the first key (1) stays; the value is replaced

grid = {(0, 0): "start", (1, 2): "tree", (3, 4): "goal"}
print(grid[(1, 2)])
OUTPUT
tuple key 5 d[[1, 2]] → TypeError: unhashable type: 'list' d[{"a": 1}] → TypeError: unhashable type: 'dict' d[{1, 2}] → TypeError: unhashable type: 'set' d[(1, [2])] → TypeError: unhashable type: 'list' {1: 'bool'} tree
🪤
1, 1.0 and True Are the Same Key1, 1.0 और True एक ही Key हैं1、1.0 和 True 是同一个键

Python treats keys as the same when they are equal and have the same hash. 1 == 1.0 == True and all three hash to 1, so the last example ended with just {1: 'bool'}: the first key object (1) stays, and only the value is replaced. Avoid mixing these types as keys.

Python keys को तब एक मानता है जब वे बराबर हों और उनका hash एक हो। 1 == 1.0 == True और तीनों का hash 1 है, इसलिए आख़िरी उदाहरण बस {1: 'bool'} पर ख़त्म हुआ: पहला key object (1) बना रहता है, और सिर्फ़ मान बदलता है। Keys में इन types को मिलाने से बचें।

当两个键相等且哈希相同时,Python 把它们视为同一个键。1 == 1.0 == True,且三者的哈希都是 1,所以最后一个例子的结果只有 {1: 'bool'}:第一个键对象(1)保留,只有值被替换。不要混用这些类型作键。

🧩
What About Your Own Objects?आपके अपने Objects का क्या?你自己定义的对象呢?

Objects of a class you write are hashable by default (by identity), even though you can change their attributes. That is fine as long as you look them up by the same object. If you define __eq__ to compare contents, you must also think about __hash__ — you will meet this when you learn classes.

आपकी लिखी class के objects default रूप से (पहचान के आधार पर) hashable होते हैं, भले ही आप उनके attributes बदल सकें। जब तक आप उन्हें उसी object से ढूँढते हैं, यह ठीक है। अगर आप सामग्री की तुलना के लिए __eq__ लिखते हैं, तो __hash__ के बारे में भी सोचना होगा — यह आप classes सीखते समय देखेंगे।

你自己写的类的对象默认是可哈希的(按身份),即使你能修改它们的属性。只要你用同一个对象去查找就没问题。如果你定义了 __eq__ 来比较内容,就必须同时考虑 __hash__ —— 学习类的时候会遇到。

Try It — Key Rules Checkerआज़माएँ — Key Rules Checker动手试试 —— 键规则检查器

Type any Python value and press Try it. The checker runs d[key] = n and tells you whether the key is allowed, and why. Try 1, then 1.0, then True, and watch the dict.

कोई भी Python मान लिखें और Try it दबाएँ। Checker d[key] = n चलाकर बताता है कि key मान्य है या नहीं, और क्यों। 1, फिर 1.0, फिर True आज़माएँ, और dict को देखें।

输入任意 Python 值并点击试一试。检查器会运行 d[key] = n,告诉你这个键是否允许以及原因。依次试试 1、1.0、True,观察字典的变化。

🔑 Key Rules CheckerKey Rules Checker键规则检查器Hashable or not? Each try runs d[key] = n.Hashable या नहीं? हर कोशिश d[key] = n चलाती है।可哈希吗?每次尝试都运行 d[key] = n。
d[] = n
Try:आज़माएँ:试试:
the dict ddict d字典 d

SectionSection第 07 节

Accessing and Changing Values ✏️मान पढ़ना और बदलना ✏️访问与修改值 ✏️

Reading — Three Waysपढ़ना — तीन तरीक़े读取 —— 三种方式

user = {"name": "Asha", "age": 30, "city": "Pune"}

print(user["name"])
try:
    print(user["email"])
except KeyError as err:
    print("KeyError:", err)

print(user.get("name"), user.get("email"), user.get("email", "n/a"))

if "email" in user:
    print(user["email"])
else:
    print("no email on file")
OUTPUT
Asha KeyError: 'email' Asha None n/a no email on file

user["email"] raises KeyError; user.get("email") returns None (or your default); "email" in user checks first. Use [ ] when a missing key would be a real bug, and .get() when missing is normal.

user["email"] KeyError देता है; user.get("email") None (या आपका default) लौटाता है; "email" in user पहले जाँचता है। जब ग़ायब key असली bug हो तब [ ] लगाएँ, और जब ग़ायब होना सामान्य हो तब .get()।

user["email"] 会抛出 KeyError;user.get("email") 返回 None(或你的默认值);"email" in user 先做检查。当缺少键意味着真正的 bug 时用 [ ],缺少键属于正常情况时用 .get()。

Writing — Add, Update, Deleteलिखना — जोड़ें, बदलें, मिटाएँ写入 —— 添加、更新、删除

user = {"name": "Asha", "age": 30}
user["city"] = "Pune"          # add a new key (goes to the end)
user["age"] = 31               # update an existing key (keeps its place)
print(user)

del user["city"]               # remove a key (KeyError if missing)
age = user.pop("age")          # remove AND return the value
print(age, user)
email = user.pop("email", None)    # safe: a default instead of KeyError
print(email)
OUTPUT
{'name': 'Asha', 'age': 31, 'city': 'Pune'} 31 {'name': 'Asha'} None

Try It — Key-Value Labआज़माएँ — Key-Value Lab动手试试 —— 键值实验室

Practise the six basic moves on one dict. Pick an operation, type a key (with quotes for text) and press Run. The dict keeps your changes. Try a missing key with [ ] and then with .get() to feel the difference.

एक dict पर छह बुनियादी काम अभ्यास करें। Operation चुनें, key लिखें (text के लिए quotes के साथ) और Run दबाएँ। Dict आपके बदलाव रखती है। फ़र्क़ महसूस करने के लिए ग़ायब key को [ ] से और फिर .get() से आज़माएँ।

在一个字典上练习六种基本操作。选择操作,输入键(文本要加引号),然后点击运行。字典会保留你的修改。用 [ ] 和 .get() 分别试试不存在的键,感受两者的区别。

🧪 Key-Value LabKey-Value Lab键值实验室Read, add, update and delete — see each pair change.पढ़ें, जोड़ें, बदलें और मिटाएँ — हर जोड़ी को बदलते देखें।读取、添加、更新、删除 —— 观察每个键值对的变化。
Try:आज़माएँ:试试:
user

SectionSection第 08 节

Dictionary Methods — The Complete Toolkit 🧰Dictionary Methods — पूरा औज़ार-बक्सा 🧰字典方法 —— 完整工具箱 🧰

A dict has 11 public methods. The three view methods — .keys(), .values() and .items() — return live views, not copies: when the dict changes, the view shows the change.

Dict में 11 public methods हैं। तीन view methods — .keys(), .values() और .items() — copies नहीं, live views लौटाते हैं: dict बदलने पर view बदलाव दिखाता है।

字典有 11 个公开方法。三个视图方法 —— .keys()、.values() 和 .items() —— 返回的是实时视图,不是副本:字典变化时,视图也会随之变化。

View MethodsView Methods视图方法

scores = {"Asha": 92, "Ravi": 78, "Meena": 85}
print(scores.keys())
print(list(scores.keys()))
print(scores.values(), sum(scores.values()))
print(scores.items())

keys_view = scores.keys()      # a LIVE view, not a copy
scores["Dev"] = 88
print(keys_view)               # the view shows the new key by itself
OUTPUT
dict_keys(['Asha', 'Ravi', 'Meena']) ['Asha', 'Ravi', 'Meena'] dict_values([92, 78, 85]) 255 dict_items([('Asha', 92), ('Ravi', 78), ('Meena', 85)]) dict_keys(['Asha', 'Ravi', 'Meena', 'Dev'])

Methods That Change the DictDict बदलने वाले Methods修改字典的方法

scores = {"Asha": 92, "Ravi": 78}
scores.update({"Meena": 85, "Dev": 73})   # merge; new keys go to the end
print(scores)
scores.update({"Asha": 99})               # existing key: new value, same place
print(scores)

val = scores.pop("Ravi")
print(val, scores.pop("Missing", -1))
last = scores.popitem()                   # removes the LAST inserted pair
print(last, scores)

groups = {}
for word in ["apple", "ant", "bee", "ball", "cat"]:
    groups.setdefault(word[0], []).append(word)
print(groups)

original = {"a": 1, "b": 2}
duplicate = original.copy()
duplicate["c"] = 3
print(original, duplicate)
merged = original | {"b": 20, "z": 26}    # Python 3.9+: | makes a NEW merged dict
print(merged)
scores.clear()
print(scores)
OUTPUT
{'Asha': 92, 'Ravi': 78, 'Meena': 85, 'Dev': 73} {'Asha': 99, 'Ravi': 78, 'Meena': 85, 'Dev': 73} 78 -1 ('Dev', 73) {'Asha': 99, 'Meena': 85} {'a': ['apple', 'ant'], 'b': ['bee', 'ball'], 'c': ['cat']} {'a': 1, 'b': 2} {'a': 1, 'b': 2, 'c': 3} {'a': 1, 'b': 20, 'z': 26} {}
🔀
Merging With || से मिलाना用 | 合并

Since Python 3.9, a | b builds a new dict with the pairs of both (the right side wins for shared keys), and a |= b updates a in place, like update().

Python 3.9 से a | b दोनों की जोड़ियों से एक नई dict बनाता है (साझा keys पर दाईं ओर वाला जीतता है), और a |= b update() की तरह a को अपनी जगह बदलता है।

从 Python 3.9 起,a | b 用两者的键值对构建一个新字典(相同的键以右边为准),而 a |= b 像 update() 一样原地更新 a。

Try It — Dict Method Simulatorआज़माएँ — Dict Method Simulator动手试试 —— 字典方法模拟器

Run any method on scores and compare before and after. Green pairs were added, orange pairs got a new value, and red pairs were removed. The line kv = scores.keys() ran once at the start — watch it update by itself. That is a live view.

scores पर कोई भी method चलाएँ और पहले व बाद की तुलना करें। हरी जोड़ियाँ जुड़ीं, नारंगी को नया मान मिला, और लाल हटाई गईं। Line kv = scores.keys() शुरू में एक बार चली थी — इसे अपने आप बदलते देखें। यही live view है।

对 scores 运行任意方法,比较之前和之后。绿色是新增的键值对,橙色是值被更新的,红色是被删除的。kv = scores.keys() 只在开始时运行过一次 —— 看它如何自己更新。这就是实时视图。

🔧 Dict Method SimulatorDict Method Simulator字典方法模拟器Changes stay between runs, like real Python.बदलाव runs के बीच बने रहते हैं, असली Python की तरह।修改会在多次运行间保留,和真实 Python 一样。
Try:आज़माएँ:试试:
beforeपहले之前
afterबाद में之后
live view kv →live view kv →实时视图 kv →

Complete Methods Referenceपूरी Methods सूची完整方法速查

Groupसमूह类别MethodMethod方法What it doesक्या करता है作用Returnsलौटाता है返回
ViewsViews视图.keys() / .values() / .items()Live views of keys / values / (key, value) pairskeys / values / (key, value) जोड़ियों के live views键 / 值 / (键, 值) 对的实时视图dict_keys …
Readपढ़ना读取d[k]Value for k; KeyError if missingk का मान; ग़ायब हो तो KeyErrork 的值;不存在时 KeyErrorvalueमान值
.get(k, default)Safe lookup; default (None) if missingसुरक्षित lookup; ग़ायब हो तो default (None)安全查找;不存在时返回默认值(None)value or defaultमान या default值或默认值
k in d / len(d)Key check (fast, hash-based) / number of pairsKey जाँच (तेज़, hash से) / जोड़ियों की गिनती检查键(快,基于哈希)/ 键值对数量bool / int
Changeबदलना修改d[k] = vAdd or updateजोड़ें या बदलें添加或更新—
.update(other) / d |= otherMerge another dict or pairsदूसरी dict या जोड़ियाँ मिलाएँ合并另一个字典或键值对None
.setdefault(k, default)Get, or add if missingपढ़ें, या ग़ायब हो तो जोड़ें取值,不存在则添加existing or new valueमौजूदा या नया मान已有值或新值
.pop(k, default)Remove and return the valueमान हटाकर लौटाएँ删除并返回值valueमान值
.popitem()Remove and return the LAST pairआख़िरी जोड़ी हटाकर लौटाएँ删除并返回最后一对tuple
del d[k] / .clear()Remove one key / all keysएक key / सब keys हटाएँ删除一个键 / 全部键— / None
Buildबनाना构建.copy() / d1 | d2Shallow copy / merged new dict (3.9+)Shallow copy / मिली हुई नई dict (3.9+)浅拷贝 / 合并出的新字典(3.9+)new dictनई dict新字典
dict.fromkeys(keys, v)New dict, same value for every keyनई dict, हर key का एक मान新字典,每个键同一个值new dictनई dict新字典

SectionSection第 09 节

The for Loop — Walking Through Dictionaries 🔁for Loop — Dictionaries में चलना 🔁for 循环 —— 遍历字典 🔁

A plain for over a dict gives the keys. Use .values() for values only, and .items() for both at once — the most common pattern.

Dict पर सादा for keys देता है। सिर्फ़ मानों के लिए .values() लगाएँ, और दोनों के लिए .items() — यह सबसे आम तरीक़ा है।

直接对字典用 for 得到的是键。只要值就用 .values(),键和值都要就用 .items() —— 这是最常见的写法。

Patterns 1–3 — Keys, Values and ItemsPatterns 1–3 — Keys, Values और Items模式 1–3 —— 键、值与键值对

ages = {"Asha": 30, "Ravi": 25, "Meena": 35}

for name in ages:                  # plain loop → keys
    print(name, end=" ")
print()
for age in ages.values():
    print(age, end=" ")
print()
print(sum(ages.values()), max(ages.values()), sum(ages.values()) / len(ages))

for name, age in ages.items():     # the most common pattern
    print(f"{name} is {age}")

adults = [name for name, age in ages.items() if age >= 30]
print(adults)
for name, age in sorted(ages.items(), key=lambda kv: kv[1]):
    print(f"{name}: {age}")
OUTPUT
Asha Ravi Meena 30 25 35 90 35 30.0 Asha is 30 Ravi is 25 Meena is 35 ['Asha', 'Meena'] Ravi: 25 Asha: 30 Meena: 35

Pattern 4 — Dict ComprehensionsPattern 4 — Dict Comprehensions模式 4 —— 字典推导式

squares = {n: n ** 2 for n in range(1, 6)}
print(squares)

prices = {"apple": 1.0, "bread": 3.0, "milk": 2.5}
with_tax = {name: price * 1.15 for name, price in prices.items()}
print(with_tax)                    # look at bread: floats are not exact!
print({name: round(price * 1.15, 2) for name, price in prices.items()})

inverted = {v: k for k, v in prices.items()}
print(inverted)
cheap = {name: price for name, price in prices.items() if price < 3}
print(cheap)
OUTPUT
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25} {'apple': 1.15, 'bread': 3.4499999999999997, 'milk': 2.875} {'apple': 1.15, 'bread': 3.45, 'milk': 2.88} {1.0: 'apple', 3.0: 'bread', 2.5: 'milk'} {'apple': 1.0, 'milk': 2.5}
🔢
Look at bread: 3.4499999999999997bread देखें: 3.4499999999999997看 bread:3.4499999999999997

3.0 * 1.15 is not exactly 3.45, because floats store numbers in binary and most decimals cannot be stored exactly. For money, round with round(x, 2) (third line) or use the decimal module.

3.0 * 1.15 ठीक 3.45 नहीं है, क्योंकि floats संख्याएँ binary में रखते हैं और ज़्यादातर दशमलव ठीक-ठीक नहीं रखे जा सकते। पैसों के लिए round(x, 2) से गोल करें (तीसरी line) या decimal module लगाएँ।

3.0 * 1.15 并不精确等于 3.45,因为浮点数以二进制存储,大多数小数无法精确表示。涉及金额时,用 round(x, 2) 取整(第三行),或使用 decimal 模块。

Don't Change a Dict While Looping Over ItLoop करते हुए Dict न बदलें不要边遍历边修改字典

ages = {"Asha": 30, "Ravi": 25, "Meena": 35, "Dev": 22}
try:
    for name in ages:
        if ages[name] < 30:
            del ages[name]         # changing the size while looping
except RuntimeError as err:
    print("RuntimeError:", err)

ages = {"Asha": 30, "Ravi": 25, "Meena": 35, "Dev": 22}
for name in list(ages):            # loop over a COPY of the keys
    if ages[name] < 30:
        del ages[name]
print(ages)

ages = {"Asha": 30, "Ravi": 25, "Meena": 35, "Dev": 22}
print({k: v for k, v in ages.items() if v >= 30})   # or build a new dict
OUTPUT
RuntimeError: dictionary changed size during iteration {'Asha': 30, 'Meena': 35} {'Asha': 30, 'Meena': 35}

Deleting (or adding) keys while looping over the same dict raises RuntimeError: dictionary changed size during iteration. Loop over a copy of the keys with list(ages), or build a new dict with a comprehension.

उसी dict पर loop करते हुए keys मिटाने (या जोड़ने) से RuntimeError: dictionary changed size during iteration आता है। list(ages) से keys की copy पर loop करें, या comprehension से नई dict बनाएँ।

在遍历字典的同时删除(或添加)键,会引发 RuntimeError: dictionary changed size during iteration。请用 list(ages) 遍历键的副本,或用推导式构建新字典。

Try It — Loop Pattern Stepperआज़माएँ — Loop Pattern Stepper动手试试 —— 循环模式单步器

Pick a pattern, edit the dict if you like, and step through it one line at a time. The current pair lights up, the loop variables show their values, and the output grows line by line. The last two tabs show the RuntimeError trap and the safe fix.

कोई pattern चुनें, चाहें तो dict बदलें, और एक-एक line चलाएँ। मौजूदा जोड़ी चमकती है, loop variables अपने मान दिखाते हैं, और output line-दर-line बढ़ता है। आख़िरी दो tabs RuntimeError जाल और सुरक्षित हल दिखाते हैं।

选择一种模式,可以修改字典,然后逐行单步执行。当前的键值对会高亮,循环变量显示它们的值,输出逐行增加。最后两个标签展示 RuntimeError 陷阱和安全的修复方法。

🔁 Loop Pattern StepperLoop Pattern Stepper循环模式单步器One line at a time. Watch keys, values and variables.एक बार में एक line। Keys, values और variables देखें।一次一行。观察键、值和变量。
outputoutput输出

SectionSection第 10 节

Nested Dictionaries — Structured Data 📂Nested Dictionaries — ढाँचेदार Data 📂嵌套字典 —— 结构化数据 📂

A value can itself be a dict (or a list). This is how you model JSON, database rows and settings files. Each [ ] reads from the result of the one before it, from left to right.

कोई मान ख़ुद एक dict (या list) हो सकता है। JSON, database rows और settings files ऐसे ही बनती हैं। हर [ ] अपने से पहले वाले के नतीजे से पढ़ता है, बाएँ से दाएँ।

值本身也可以是字典(或列表)。JSON、数据库行和配置文件都是这样建模的。每个 [ ] 都从前一个的结果中读取,从左到右。

users = {
    "asha": {
        "name": "Asha Verma",
        "age": 30,
        "skills": ["Python", "SQL"],
        "active": True,
    },
    "ravi": {
        "name": "Ravi Kumar",
        "age": 25,
        "skills": ["Go", "Rust"],
        "active": False,
    },
}
print(users["asha"]["name"])
print(users["asha"]["skills"][0])
print(users.get("meena", {}).get("email", "n/a"))    # safe chained access

for username, info in users.items():
    status = "active" if info["active"] else "inactive"
    print(f"{info['name']:<12} — {status:<8} — {len(info['skills'])} skills")

users["asha"]["skills"].append("Kubernetes")
print(users["asha"]["skills"])
OUTPUT
Asha Verma Python n/a Asha Verma — active — 2 skills Ravi Kumar — inactive — 2 skills ['Python', 'SQL', 'Kubernetes']

Try It — Nested Dict Explorerआज़माएँ — Nested Dict Explorer动手试试 —— 嵌套字典探索器

Click your way into the users dict from the code above. Each click adds one [ ] to the path. Then test safe access: type a user and a field that may not exist, and compare brackets with the chained .get().

ऊपर के code की users dict में click करते हुए अंदर जाएँ। हर click रास्ते में एक [ ] जोड़ता है। फिर सुरक्षित पहुँच जाँचें: ऐसा user और field लिखें जो शायद मौजूद न हो, और brackets की तुलना .get() की लड़ी से करें।

点击进入上面代码中的 users 字典。每次点击都会在路径上加一个 [ ]。然后测试安全访问:输入一个可能不存在的用户和字段,比较方括号和链式 .get() 的区别。

📂 Nested Dict ExplorerNested Dict Explorer嵌套字典探索器Build users[...][...] by clicking. Then try safe .get() chains.Click करके users[...][...] बनाएँ। फिर सुरक्षित .get() लड़ियाँ आज़माएँ।点击构建 users[...][...],再试试安全的 .get() 链。
safe access testसुरक्षित पहुँच जाँच安全访问测试
Try:आज़माएँ:试试:

SectionSection第 11 节

Complete Practice Program — Word Frequency Counter 📊पूरा अभ्यास Program — शब्द-गिनती 📊完整练习程序 —— 词频统计 📊

This program uses .get(w, 0) + 1 to count, sorted(... key=...) to rank, a dict comprehension to filter, setdefault to group, and .get() for safe lookups. The output below is a real run.

यह program गिनने के लिए .get(w, 0) + 1, क्रम देने के लिए sorted(... key=...), छाँटने के लिए dict comprehension, समूह बनाने के लिए setdefault, और सुरक्षित lookup के लिए .get() लगाता है। नीचे का output असली run है।

这个程序用 .get(w, 0) + 1 计数,用 sorted(... key=...) 排名,用字典推导式过滤,用 setdefault 分组,用 .get() 安全查找。下面的输出是真实运行结果。

# word_counter.py — a real dictionary workout

def count_words(text):
    """Return a dict mapping word → count."""
    counts = {}
    for word in text.lower().split():
        word = word.strip(".,!?;:\"'—")
        if word:
            counts[word] = counts.get(word, 0) + 1
    return counts

def main():
    text = """
    The quick brown fox jumps over the lazy dog.
    The dog barks. The fox runs. The lazy dog sleeps again.
    Python makes counting words a breeze — the dict does the work.
    """

    line = "─" * 40
    counts = count_words(text)

    print(f"{line}\n  WORD FREQUENCY REPORT\n{line}")
    print(f"  Unique words: {len(counts)}")
    print(f"  Total words:  {sum(counts.values())}")

    # Top 5: sort the (word, count) pairs by count, biggest first
    top5 = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)[:5]
    print(f"\n  {'WORD':<10}{'COUNT':>6}  BAR")
    for word, count in top5:
        print(f"  {word:<10}{count:>6}  {'█' * count}")

    # Dict comprehension: words that appear 2+ times
    frequent = {w: c for w, c in counts.items() if c >= 2}
    print(f"\n  Words appearing 2+ times: {frequent}")

    # setdefault: group words by length
    by_length = {}
    for word in counts:
        by_length.setdefault(len(word), []).append(word)
    print("\n  Grouped by length:")
    for length, words in sorted(by_length.items()):
        print(f"    {length} chars: {words}")

    # Safe lookup with .get()
    for query in ["the", "missing"]:
        print(f"  '{query}' appears {counts.get(query, 0)} time(s)")

if __name__ == "__main__":
    main()
OUTPUT
──────────────────────────────────────── WORD FREQUENCY REPORT ──────────────────────────────────────── Unique words: 21 Total words: 31 WORD COUNT BAR the 7 ███████ dog 3 ███ fox 2 ██ lazy 2 ██ quick 1 █ Words appearing 2+ times: {'the': 7, 'fox': 2, 'lazy': 2, 'dog': 3} Grouped by length: 1 chars: ['a'] 3 chars: ['the', 'fox', 'dog'] 4 chars: ['over', 'lazy', 'runs', 'dict', 'does', 'work'] 5 chars: ['quick', 'brown', 'jumps', 'barks', 'again', 'makes', 'words'] 6 chars: ['sleeps', 'python', 'breeze'] 8 chars: ['counting'] 'the' appears 7 time(s) 'missing' appears 0 time(s)
🎯
Two Details Worth Noticingदो बातें ध्यान देने लायक़两个值得注意的细节

1. The strip() list includes the dash —; otherwise the lone "—" in the text would be counted as a word.
2. In the top 5, "fox" and "lazy" (both 2) keep the order in which they first appeared, because sorted() is stable and the dict remembers insertion order.

1. strip() की सूची में dash — भी है; नहीं तो text का अकेला "—" एक शब्द गिना जाता।
2. Top 5 में "fox" और "lazy" (दोनों 2) उसी क्रम में रहते हैं जिसमें वे पहली बार आए, क्योंकि sorted() stable है और dict डालने का क्रम याद रखती है।

1. strip() 的字符列表里包含破折号 —;否则文本中单独的 "—" 会被当成一个单词。
2. 在前 5 名中,"fox" 和 "lazy"(都是 2 次)保持它们首次出现的顺序,因为 sorted() 是稳定排序,而字典记住了插入顺序。


SectionSection第 12 节

Golden Rules 🏆सुनहरे नियम 🏆黄金法则 🏆

🐍 Python Dictionaries — 8 RulesPython Dictionaries — 8 नियमPython 字典 —— 8 条法则
1
Keys must be hashable. str, int, float, bool, None, frozenset and tuples of these work. Lists, dicts and sets do not: TypeError: unhashable type.
Keys hashable होनी चाहिए। str, int, float, bool, None, frozenset और इनके tuples चलते हैं। Lists, dicts और sets नहीं: TypeError: unhashable type।
键必须可哈希。str、int、float、bool、None、frozenset 以及由它们组成的元组都可以。列表、字典和集合不行:TypeError: unhashable type。
2
Keys are unique — and equal keys are the same key. Assigning to an existing key replaces its value. 1, 1.0 and True count as one key. For several values per key, store a list (or use collections.defaultdict(list)).
Keys अनोखी हैं — और बराबर keys एक ही key हैं। मौजूदा key पर assign करने से उसका मान बदल जाता है। 1, 1.0 और True एक key गिनी जाती हैं। एक key के कई मानों के लिए list रखें (या collections.defaultdict(list) लगाएँ)।
键是唯一的 —— 相等的键就是同一个键。给已有的键赋值会替换它的值。1、1.0 和 True 算作同一个键。一个键要对应多个值,就存一个列表(或使用 collections.defaultdict(list))。
3
Use .get() when a key might be missing. d.get("k", default) never crashes; d["k"] raises KeyError. Keep the crash for cases where a missing key is a real bug.
जब key ग़ायब हो सकती हो, .get() लगाएँ। d.get("k", default) कभी नहीं रुकता; d["k"] KeyError देता है। रुकना उन मामलों के लिए रखें जहाँ ग़ायब key असली bug हो।
键可能不存在时,用 .get()。d.get("k", default) 永不报错;d["k"] 会抛出 KeyError。只有当缺键意味着真正的 bug 时才让它报错。
4
key in d is fast. It uses the hash, so it takes about the same time for 10 or 10 million keys. Never search list(d.keys()) instead.
key in d तेज़ है। यह hash लगाता है, इसलिए 10 या 1 करोड़ keys के लिए लगभग उतना ही समय लेता है। इसकी जगह कभी list(d.keys()) में न खोजें।
key in d 很快。它借助哈希,所以 10 个键和 1000 万个键耗时差不多。永远不要改为在 list(d.keys()) 里搜索。
5
Loop with .items() when you need both. for k, v in d.items(): is clearer than looking up d[k] inside the loop.
दोनों चाहिए तो .items() से loop करें। for k, v in d.items(): loop के अंदर d[k] ढूँढने से ज़्यादा साफ़ है।
键和值都需要时,用 .items() 遍历。for k, v in d.items(): 比在循环里再查 d[k] 更清晰。
6
Never add or delete keys while looping over the dict. You get RuntimeError. Loop over list(d) or build a new dict with a comprehension.
Dict पर loop करते हुए keys कभी न जोड़ें या मिटाएँ। RuntimeError मिलता है। list(d) पर loop करें या comprehension से नई dict बनाएँ।
绝不在遍历字典时添加或删除键。会得到 RuntimeError。请遍历 list(d),或用推导式构建新字典。
7
Insertion order is kept (Python 3.7+). Dicts list their keys in the order you added them. Updating a value does not move its key.
डालने का क्रम बना रहता है (Python 3.7+)। Dicts keys को उसी क्रम में दिखाती हैं जिसमें आपने डालीं। मान बदलने से key अपनी जगह से नहीं हिलती।
保持插入顺序(Python 3.7+)。字典按你添加的顺序列出键。更新值不会移动键的位置。
8
{} is an empty dict, not a set. Use set() for an empty set. Braces with key: value pairs make a dict; braces with plain items make a set.
{} ख़ाली dict है, set नहीं। ख़ाली set के लिए set() लगाएँ। key: value जोड़ियों वाले braces dict बनाते हैं; सादे items वाले braces set।
{} 是空字典,不是集合。空集合请用 set()。花括号里是 key: value 对就是字典;是普通的项就是集合。
LIVELIVE互动Quick Checkछोटी जाँच小测验

Six questions on dictionaries. Pick an answer to see why.

Dictionaries पर छह सवाल। जवाब चुनें और कारण देखें।

关于字典的六道题。选择答案查看解释。

🗂️
Key Takeawayमुख्य सीख核心要点

A dict maps unique, hashable keys to values. Python hashes the key to jump straight to a slot, so lookups, inserts and in checks take about the same time however big the dict grows. Read with [ ] or .get(), change with d[k] = v, update(), pop() and del, loop with .items(), and never change the size of a dict while looping over it.

Dict अनोखी, hashable keys को मानों से जोड़ती है। Python key का hash निकालकर सीधे slot पर पहुँचता है, इसलिए dict कितनी भी बड़ी हो, lookup, insert और in जाँच में लगभग उतना ही समय लगता है। [ ] या .get() से पढ़ें, d[k] = v, update(), pop() और del से बदलें, .items() से loop करें, और dict पर loop करते हुए उसका आकार कभी न बदलें।

字典把唯一且可哈希的键映射到值。Python 计算键的哈希,直接跳到对应槽位,所以无论字典多大,查找、插入和 in 检查的耗时都差不多。用 [ ] 或 .get() 读取,用 d[k] = v、update()、pop() 和 del 修改,用 .items() 遍历,并且绝不在遍历时改变字典的大小。

🐍 Try Python Yourself

Write, run and visualize Python step by step. No install needed.