Skip to content
This page has been auto-translated and may contain errors.View in English

शब्दकोश

docs.scrimba.com

लिस्ट आपको स्थिति के आधार पर चीजें देखने देते हैं। लेकिन अक्सर आप किसी चीज को नाम से देखना चाहते हैं। "मुझे item 3 दो" नहीं, बल्कि "मुझे राज का स्कोर दो"। एक शब्दकोश डेटा को key-value जोड़े के रूप में संग्रहीत करता है: आप किसी मान को स्थिति के बजाय इसकी key से देखते हैं।

जब किसी लिस्ट की स्थितीय index अर्थपूर्ण नहीं है, तो शब्दकोश सही संरचना है। Dicts मनमानी keys को values के साथ मैप करते हैं, जो आपको O(1) समय में नामांकित lookup देता है। एक लीडरबोर्ड, एक JSON प्रतिक्रिया, एक कॉन्फ़िग फाइल: सभी स्वाभाविक रूप से key-value mappings के रूप में व्यक्त किए जाते हैं।

एक dict एक key-value स्टोर है जिसमें औसत O(1) lookup, insertion, और deletion है (O(1) का अर्थ है कि लागत समान रहती है चाहे dict कितना भी बड़ा हो, क्योंकि keys hashing द्वारा मिलती हैं, key को एक संख्या में बदलते हुए जो सीधे इसके स्लॉट की ओर इशारा करती है)। Keys को hashable होना चाहिए, जिसका अर्थ है कि उनकी सामग्री कभी नहीं बदलती ताकि संख्या स्थिर रहे: str, int, और tuple योग्य हैं, list नहीं है। Values कोई भी object हो सकता है। Python 3.7 के बाद से, dicts keys को उसी क्रम में रखते हैं जिस क्रम में आपने उन्हें insert किया है, जो तब मायने रखता है जब आप किसी को serialize या display करते हैं। एक ही संरचना Python के बहुत कुछ surface के नीचे शक्तिशाली करती है, जिसमें आपके स्वयं के objects की विशेषताएं भी शामिल हैं, इसलिए dicts को अच्छी तरह से जानना लायक है। Lists अध्याय स्थिति-आधारित cousin को कवर करता है।

एक शब्दकोश बनाना

घुंघराले ब्रेसिज़ एक colon के साथ प्रत्येक key और value के बीच, और जोड़े के बीच commas। Keys लगभग हमेशा strings होती हैं। Values कुछ भी हो सकता है: संख्याएं, strings, अन्य lists, यहां तक कि अन्य शब्दकोश।

Dict literals घुंघराले ब्रेसिज़ का उपयोग करते हैं key: value सिंटैक्स के साथ। Keys कोई भी immutable (hashable) type हो सकते हैं: strings, integers, tuples। Values कोई भी Python object हो सकता है। Dicts insertion order को preserve करते हैं, इसलिए जब आप iterate करते हैं, तो आप items को उसी क्रम में पाते हैं जिस क्रम में वे जोड़े गए थे।

Dict literals को बाएं से दाएं evaluate किया जाता है। Keys को hashable होना चाहिए (उनकी सामग्री नहीं बदल सकती, इसलिए Python जिस संख्या के अंतर्गत उन्हें फाइल करता है वह रहती है): str, int, और tuple योग्य हैं, list और dict नहीं हैं। Values के लिए कोई ऐसी प्रतिबंध नहीं है। Insertion order Python 3.7 के बाद से भाषा guarantee है, इसलिए iteration और serialisation reproducible हैं। एक quiet trap: एकल literal में duplicate key raise नहीं करती है, यह last value रखती है और पहले वाली को drop कर देती है।

python
# खिलाड़ी
player = {
    "name": "राज",
    "score": 87,
    "level": 5,
    "alive": True,
}
Junoएक शब्दकोश बनाना घुंघराले ब्रेसिज़, एक colon प्रत्येक key और इसके value के बीच, pairs के बीच commas। Keys आमतौर पर strings होती हैं, values कुछ भी हो सकता है, यहां तक कि एक अन्य शब्दकोश भी। जिस क्रम में आप चीजें जोड़ते हैं वही क्रम है जिसमें आप उन्हें वापस पाते हैं, जिस पर मैं expected से अधिक lean करता हूं।
Junoएक शब्दकोश बनानाkey: value pairs के साथ घुंघराले ब्रेसिज़। Keys कोई भी immutable type हो सकते हैं (str, int, tuple), values कोई भी object हो सकता है। Iteration insertion order को follow करता है, इसलिए एक dict ठीक है जब order matters।
Junoएक शब्दकोश बनाना Keys को hashable होना चाहिए, इसलिए str, int, और tuple in हैं, list और dict out हैं। Insertion order 3.7 के बाद से guaranteed है, इसलिए आप output के लिए इस पर निर्भर कर सकते हैं। Duplicate-key literal को देखें: यह silently last value लेता है, कोई warning नहीं।

मान एक्सेस करना

key के साथ square brackets का उपयोग करके value पाएं। यदि key मौजूद नहीं है, तो Python एक KeyError raise करता है। .get() का उपयोग करें जब आप सुनिश्चित नहीं हैं कि key वहां है: यह None return करता है crash के बजाय, या एक default value जो आप specify करते हैं।

Square bracket access एक missing key पर KeyError raise करता है। .get(key) एक miss पर None return करता है। .get(key, default) default के बजाय return करता है। .get() का उपयोग करें जब भी key की presence uncertain हो; यह wrap करने से ज्यादा safe और readable है एक try/except में।

Square-bracket access key को hash करके और matching slot को read करके देखता है, जो औसतन O(1) है (size के बावजूद flat cost)। एक miss पर यह KeyError raise करता है। .get(key, default=None) एक ही lookup करता है लेकिन miss पर raise के बजाय default return करता है, इसलिए जब key की presence uncertain हो तो यह सही call है। एक bracket access से पहले guard करने के लिए, key in d भी O(1) है; in को pick करें जब आपको केवल yes-या-no चाहिए, .get() को जब आप value या एक fallback एक step में चाहिए।

python
player = {"name": "राज", "score": 87}

player["name"]    # "राज"
player["score"]   # 87
player["lives"]   # KeyError (key doesn't exist)
python
player.get("score")          # 87
player.get("lives")          # None (no error, returns None by default)
player.get("lives", 3)       # 3   (use this default if key is absent)

.get() ज्यादा safe है जब भी key missing हो सकती है:

python
count = inventory.get("arrows", 0)   # 0 if "arrows" isn't in the dict
Junoमान एक्सेस करनाd["key"] आपको value देता है, लेकिन `KeyError` raise करता है अगर वह key नहीं है। जब आप निश्चित नहीं हैं, तो .get() के लिए पहुंचें: यह `None` return करता है crash के बजाय, या एक default जो आप pass करते हैं। मैं अब सब कुछ default करता हूं और मेरे programs missing keys पर crashing बंद कर गए।
Junoमान एक्सेस करना Bracket access एक miss पर `KeyError` raise करता है, .get(key) `None` return करता है, और .get(key, default) जो कुछ आप pass करते हैं return करता है। .get() का उपयोग करें जब key absent हो सकती है: access को try/except में wrap करने से cleaner।
Junoमान एक्सेस करनाd[key] और .get() दोनों एक O(1) lookup करते हैं, difference सिर्फ miss पर क्या होता है: raise बनाम default return करना। `key in d` का उपयोग करें जब आप yes-या-no चाहें, .get() जब आप value-या-fallback एक step में चाहें।

जोड़ना और अपडेट करना

Square brackets के साथ एक key को assign करें। यदि key पहले से exists करती है, तो value replace हो जाता है। यदि यह अभी तक मौजूद नहीं है, तो एक नई entry बनाई जाती है। .update() का उपयोग करके एक पूरे अन्य शब्दकोश को एक साथ merge करें।

एक key को assign करना औसतन O(1) है और दोनों काम करता है: यह नई key के लिए entry बनाता है, existing key के लिए value replace करता है। .update() एक अन्य dict या key-value pairs का एक iterable स्वीकार करता है और प्रत्येक entry के लिए उसी assignment को apply करता है, existing keys को overwrite करते हुए।

d[key] = value key को hash करता है और एक O(1) औसत step में insert या overwrite करता है, इसलिए कोई अलग "add" और "update" नहीं है: assignment दोनों करता है। .update(other) एक ही operation है other में प्रत्येक entry के लिए run किया जाता है, कोई shared key पर overwriting करता है। merging के लिए बिना original को mutate किए, | operator (Python 3.9+) एक नया dict return करता है और दोनों inputs को untouched छोड़ देता है, जबकि |= जगह पर mutate करता है .update() की तरह। | के लिए पहुंचें जब एक function को dict को mutate नहीं करना चाहिए जो इसका caller अभी भी hold करता है।

python
player = {"name": "राज", "score": 87}

player["score"] = 92        # update existing
player["level"] = 5         # add new key
python
extras = {"level": 5, "alive": True}
player.update(extras)   # adds/overwrites with keys from extras
Junoजोड़ना और अपडेट करना Square brackets के साथ एक key को assign करें: अगर यह पहले से वहां है तो value replace हो जाता है, अगर नहीं तो एक नई entry दिखाई देती है। एक syntax दोनों को handle करता है, पहले check करने की जरूरत नहीं। एक पूरे अन्य शब्दकोश को एक बार में fold करने के लिए `.update()` का उपयोग करें।
Junoजोड़ना और अपडेट करनाd[key] = value एक move में create या replace करता है, इसलिए distinct add बनाम update नहीं है। .update(other) एक पूरे dict को merge करता है, कोई shared keys को overwrite करता है। दोनों प्रति key O(1) हैं।
Junoजोड़ना और अपडेट करना Assignment एक O(1) step में insert या overwrite करता है, और .update() वह repeated प्रति entry है। जब आप original को नहीं touch करना चाहते, | एक fresh merged dict return करता है जबकि |= जगह पर mutate करता है। एक function के अंदर | का उपयोग करें इसलिए आप quietly एक dict को change नहीं करते जो caller अभी भी hold करता है।

आइटम हटाना

हटाने के चार तरीके हैं। .pop() एक key को हटाता है और आपको value वापस देता है। .pop() एक default के साथ safe है जब key नहीं हो सकती है। del एक key को return value के बिना हटाता है। .clear() पूरे शब्दकोश को empty करता है।

.pop(key) एक miss पर KeyError raise करता है। .pop(key, default) default return करता है, जो इसे safe removal method बनाता है। del d[key] key को कोई return value के साथ हटाता है और एक miss पर KeyError raise करता है। .clear() सभी entries को हटाता है लेकिन dict object को ही रखता है।

.pop(key, default) एक O(1) औसत lookup में remove और return करता है, और default इसे miss-safe बनाता है; इसके बिना, एक missing key KeyError raise करता है। del d[key] return value के बिना हटाता है और एक miss पर raise करता है। .clear() dict को empty करता है लेकिन same object को रखता है, इसलिए कोई अन्य name जो इसकी ओर इशारा करता है एक empty dict देखता है। failure mode को याद रखने के लिए: एक dict को mutate करना जबकि आप इसके through iterate करते हैं mid-loop में RuntimeError raise करता है। fix है पहले आप remove करने की plan करते हैं उन keys को snapshot करना, for key in list(d): के साथ, फिर original से remove करना।

python
player = {"name": "राज", "score": 87, "level": 5}

player.pop("level")            # removes "level" and returns 5
player.pop("lives", None)      # safe pop, returns None if key absent
del player["score"]            # removes "score", no return value
player.clear()                 # removes everything

.pop() एक default के साथ key को remove करने का safest तरीका है जो नहीं हो सकती है।

Junoआइटम हटाना.pop(key) एक key को हटाता है और आपको इसकी value वापस देता है, और .pop(key, None) शांत रहता है जब key नहीं हो सकती है। del d[key] कुछ return किए बिना hटाता है, .clear() बाकी को empty करता है। .pop() पर default ने मुझे `KeyError` surprises से बहुत सारे बचाए हैं।
Junoआइटम हटाना.pop(key) एक miss पर raise करता है, .pop(key, default) नहीं करता, जो इसे safe choice बनाता है। del d[key] कोई return के साथ हटाता है और एक miss पर raise करता है; .clear() dict को empty करता है लेकिन object को ही रखता है।
Junoआइटम हटाना.pop(key, default) आपका miss-safe remove-और-return है; del और bracket-pop एक missing key पर raise करते हैं। जो बिट करता है: iterating करते समय remove करना `RuntimeError` throw करता है। पहले for key in list(d): के साथ snapshot करें, फिर original से delete करें।

पुनरावृति

तीन views आपको एक dictionary के विभिन्न भागों के through loop करने देते हैं। Dict को सीधे iterate करना आपको keys देता है। .values() values देता है। .items() दोनों एक बार में देता है और यह है जो आप most का use करेंगे: प्रत्येक pair को clean, readable loops के लिए दो names में unpack करें।

.keys(), .values(), और .items() view objects return करते हैं, lists नहीं। Views dict की current state को dynamically reflect करते हैं: यदि आप dict को modify करते हैं, तो view तुरंत update हो जाता है। .items() most loops के लिए most useful है क्योंकि tuple unpacking for k, v in d.items() cleanly read करता है।

.keys(), .values(), और .items() view objects return करते हैं (dict पर live windows, अलग lists नहीं)। एक view कुछ नहीं copy करता है और dict की current state को reflect करता है, इसलिए यदि dict changes करता है, तो view उसके साथ changes करता है। क्योंकि keys unique और hashable हैं, keys view set algebra को support करता है: d.keys() & other.keys() shared keys को find करता है, - difference को find करता है, जो दो configs को diff करने के लिए handy है। एक ही mutate-during-iteration trap यहां apply करता है; यदि आप loop करते समय dict को change करना चाहते हैं, तो list(d.items()) के साथ snapshot पर iterate करें।

python
player = {"name": "राज", "score": 87, "level": 5}

for key in player:               # iterate keys (most common)
    print(key)

for key in player.keys():        # same, explicit keys view
    print(key)

for value in player.values():    # the values
    print(value)

for key, value in player.items():   # both, most useful
    print(f"{key}: {value}")

.items() है जो आप most का use करेंगे। प्रत्येक pair को दो names में unpack करना loop को readable बनाता है।

Junoपुनरावृति एक dict को सीधे loop करें और आप इसकी keys पाते हैं। .values() values देता है, और .items() दोनों एक बार में देता है, जो है जिसके लिए आप most reach करेंगे। प्रत्येक pair को दो names में unpack करना जैसे for key, value in player.items() मेरे loops को बहुत easier बनाने के लिए read करना।
Junoपुनरावृति.keys(), .values(), और .items() live views return करते हैं, lists नहीं, इसलिए वे dict को track करते हैं जैसे यह changes करता है। .items() के साथ for k, v in d.items() cleanest read करता है और है loop आप most बार लिखेंगे।
Junoपुनरावृति तीनों views live windows हैं, copies नहीं, इसलिए वे dict को reflect करते हैं जैसे यह changes करता है। Keys view set algebra करता है, इसलिए d.keys() & other.keys() दो dicts को एक line में diff करता है। समान rule removal के रूप में: iterate करते समय mutate न करें, यदि आप must करते हैं तो list(d.items()) के साथ snapshot करें।

सदस्यता जांचना

in checks करता है कि क्या एक key dictionary में exists करती है। यह values को check नहीं करता, केवल keys को। checking करने के लिए कि क्या कुछ present नहीं है, not in का उपयोग करें।

in और not in dicts के लिए O(1) हैं, और वे केवल keys को check करते हैं। values को check करने के लिए, आप in d.values() का उपयोग करेंगे, लेकिन यह O(n) है क्योंकि values indexed नहीं हैं।

key in d key को hash करके और एक slot को read करके find करता है: O(1) औसत, flat कोई बात नहीं dict कितना बड़ा है। value in d.values() को values को एक-एक करके walk करना पड़ता है: O(n), cost size के साथ grows करता है। वह asymmetry है पूरा reason जो आप look up करते हैं वह keys के रूप में store करने के लिए values को scan करने के बजाय: यदि आप frequently values को search करते हुए खुद को पाते हैं, तो आप शायद dict को दूसरे तरीके से keyed चाहते हैं, या एक second dict mapping value back to key।

python
player = {"name": "राज", "score": 87}

"name"  in player      # True
"lives" in player      # False
"lives" not in player  # True

in केवल keys को check करता है। values को check करने के लिए, in player.values() का उपयोग करें, हालांकि यह rarely आवश्यक है।

Junoसदस्यता जांचनाin बताता है कि क्या key dict में है, और केवल एक key, कभी value नहीं। यह fast stays करता है कोई बात नहीं dict कितना बड़ा हो जाता है। इसे not in को flip करें यह check करने के लिए कि क्या कुछ absent है।
Junoसदस्यता जांचनाin और not in केवल keys को check करते हैं, O(1) में। value को check करने के लिए `value in d.values()` की जरूरत है, जो O(n) है क्योंकि values indexed नहीं हैं। इसलिए key के द्वारा चीजों को look up करने के चारों ओर design करें।
Junoसदस्यता जांचनाkey in d O(1) है, value in d.values() O(n) है। यह gap है reason को key एक dict key पर जो भी आप search करते हैं। यदि आप constantly values को scan करते हैं, तो आपके पास dict गलत तरीके से round है; एक reverse map add करें।

नेस्टेड शब्दकोश

Values खुद को शब्दकोश हो सकते हैं। यही है कैसे आप structured data को multiple levels के साथ represent करते हैं: एक player जो एक stats section है, एक config file sub-sections के साथ। दो sets of square brackets एक nested value को access करते हैं: पहला outer key को pick करता है, दूसरा inner key को pick करता है।

Nested dicts शब्दकोश हैं जहां values खुद dicts हैं। chained subscripts के साथ access करें। एक inner dict को mutate करना outer dict को affect करता है क्योंकि outer dict एक reference को same object पर रखता है। जहां possible हो वहां nesting को shallow रखें: deep nesting quickly becomes hard read और navigate करना।

एक nested dict outer dicts को references पर hold करता है, उनकी copies नहीं (एक reference है एक pointer एक shared object को, इसलिए दो names एक same inner dict को point कर सकते हैं)। यही है जहां copying bites: d.copy() एक shallow copy है, यह outer dict को duplicate करता है लेकिन inner dicts अभी भी shared हैं, इसलिए changing one through copy को change करता है original में भी। जब आपको copy को fully independent की जरूरत है, copy.deepcopy() पूरे tree को walk करता है और हर level को duplicate करता है। पहले इसके लिए reach करें आप एक config को code को hand करते हैं जो इसे mutate कर सकता है। हर bracket step है अपना own O(1) lookup, इसलिए depth speed में कुछ भी cost नहीं करता है, केवल readability में।

python
users = {
    "राज": {"score": 87, "level": 5},
    "प्रिया": {"score": 74, "level": 3},
}

users["राज"]["score"]   # 87
users["प्रिया"]["level"]     # 3

chained square brackets के साथ access करें। deeply nested structures के लिए, यह unwieldy बन सकता है, इसलिए जहां आप कर सकें वहां nesting को shallow रखें।

Junoनेस्टेड शब्दकोश एक value एक पूरा dictionary हो सकता है its own का, जो है कैसे आप structured data hold करते हैं जैसे एक player एक stats section के साथ। दो sets brackets reach करते हैं: पहला outer key को picks करता है, दूसरा picks करता है इसके अंदर से। Handy, लेकिन मैं बहुत deep nest नहीं करने की कोशिश करता हूं या यह fiddly हो जाता है read करना।
Junoनेस्टेड शब्दकोश Nested dicts हैं dicts जिनके values dicts हैं; reach करें chained brackets के साथ। Outer dict एक reference को inner को hold करता है, इसलिए changing inner dict दिखाई देता है everywhere it's referenced। Nesting को shallow रखें या यह navigate करना hard हो जाता है।
Junoनेस्टेड शब्दकोश Outer dict inner dicts को references store करता है, इसलिए .copy() है shallow: copy उन inner dicts को share करता है और एक mutation leaks दोनों के across करता है। Use करें copy.deepcopy() जब आपको real independence की जरूरत है। Depth है speed पर free, readability पर costly, इसलिए stay करें shallow।

setdefault

.setdefault() एक key को read करता है यदि यह exists करता है, या इसे एक default value को set करता है यदि यह नहीं करता है, फिर value को return करता है। यह useful है जब आपको एक key को exist करने की जरूरत है लेकिन आप इसे overwrite नहीं करना चाहते यदि यह पहले से है।

.setdefault(key, default) एक read-या-create है एक call में: यदि key exists करता है, return करें इसके current value को बिना कुछ change किए; यदि यह नहीं करता है, insert करें default को और return करें। common use case है grouped structures को एक अलग existence check के बिना build करना।

.setdefault(key, default) एक O(1) lookup है जो reads-या-creates: present keys return करते हैं उनकी existing value को untouched, absent keys को default inserted मिलता है और return किया जाता है। catch worth knowing है: default एक ordinary argument है, इसलिए यह हमेशा built है यहां तक कि जब key already exists करता है। यदि वह default expensive है construct करने के लिए (एक fresh object, एक function call), आप pay करते हैं हर call के लिए। defaultdict, अगली बार cover किया, इसे sidestep करता है एक factory को केवल एक miss पर running करके। everyday "group items into lists" pattern के लिए, .setdefault(key, []).append(...) है standard one-liner जो एक key in d check को replaces करता है।

python
inventory = {}

inventory.setdefault("arrows", 0)    # sets "arrows": 0, returns 0
inventory.setdefault("arrows", 10)   # "arrows" already exists, no change, returns 0

यह useful है grouped structures को बिना पहले key existence को check किए build करने के लिए:

python
groups = {}

for name, team in players:
    groups.setdefault(team, []).append(name)
Junosetdefault.setdefault(key, default) एक key को read करता है यदि यह है, या यदि यह नहीं है तो इसे default को set करता है और return करता है। यह tidy तरीका है एक key को make sure करने का exists बिना एक value को clobber किए जो पहले से है। मैं इसे most use करता हूं grouping के लिए, "is this key here yet?" check की जरूरत नहीं है।
Junosetdefault.setdefault(key, default) एक existing value को return करता है unchanged, या एक miss पर default को insert करता है और return करता है। payoff है grouping: d.setdefault(k, []).append(x) builds करता है lists per key एक अलग existence check के बिना।
Junosetdefault एक O(1) read-या-create, लेकिन default हमेशा built है यहां तक कि एक hit पर, इसलिए एक expensive default costs आप हर call। यह बिल्कुल क्या है defaultdict की on-miss factory fixes। grouping के लिए, .setdefault(k, []).append(x) है one-liner जो key in d check को retire करता है।

collections.defaultdict और Counter

standard library के दो dict subclasses हैं जो common patterns को automatically handle करते हैं। defaultdict एक default value को missing keys के लिए create करता है इसलिए आपको कभी KeyError नहीं मिलता है। Counter count करता है कि कितनी बार प्रत्येक item एक sequence में दिखाई देता है और आपको results को एक dict के रूप में देता है।

defaultdict एक callable को लेता है जो new keys के लिए default value produce करता है, .setdefault() की जरूरत को eliminate करता है। Counter एक specialised dict है frequency counting के लिए एक .most_common() method के साथ। दोनों dict subclasses हैं, इसलिए सभी standard dict operations उन पर काम करते हैं।

defaultdict(factory) को factory (एक zero-argument callable, जैसे list या int) run करता है पहली बार आप एक missing key को read करते हैं, result को store करते हैं, और return करते हैं, इसलिए d[k] कभी KeyError raise नहीं करता है। यह key difference है .setdefault() से: factory केवल एक miss पर fires करता है, इसलिए एक expensive default common path पर कुछ नहीं costs करता है। एक gotcha to flag: क्योंकि एक plain read एक missing key को create करता है, मेरे just checking d[k] can grow dict करता है, इसलिए k in d का उपयोग करें जब आप केवल test करना चाहते हैं, insert नहीं। Counter एक dict है tallying के लिए built: एक sequence को feed करें और यह occurrences को count करता है, और .most_common(n) top n को count के द्वारा return करता है। दोनों collections module में live हैं।

defaultdict और Counter standard library में live हैं, इसलिए उन्हें पहले importing की जरूरत है। Imports को full treatment मिलता है Modules अध्याय में।

python
from collections import defaultdict

groups = defaultdict(list)
for name, team in players:
    groups[team].append(name)   # no KeyError if team is new
python
from collections import Counter

words = ["cat", "dog", "cat", "bird", "cat", "dog"]
counts = Counter(words)
# Counter({'cat': 3, 'dog': 2, 'bird': 1})

counts.most_common(2)   # [('cat', 3), ('dog', 2)]

Counter बहुत सारे "count things in a loop" boilerplate को saves करता है।

Junocollections.defaultdict और Counterdefaultdict किसी भी missing key के लिए एक default को fill करता है, इसलिए grouping और counting को `KeyError` throw करना बंद करता है। Counter tally करता है कि कितनी बार प्रत्येक item एक sequence में shows होता है और इसे dict के रूप में hand करता है। पहली बार मैंने एक hand-written counting loop को `Counter` के लिए swap किया, आधा मेरा code disappear हो गया।
Junocollections.defaultdict और Counterdefaultdict(list) या defaultdict(int) auto-create करता है default एक नई key पर, `.setdefault()` को grouping और counting के लिए retire करता है। `Counter` एक dict है tuned frequencies के लिए, .most_common(n) के साथ built in। दोनों dict subclasses हैं, इसलिए सब कुछ जो आप know करते हैं अभी भी काम करता है।
Junocollections.defaultdict और Counterdefaultdict का factory केवल एक miss पर run करता है, इसलिए unlike `.setdefault()` एक expensive default common path पर कुछ नहीं costs करता है। trap: एक missing key को read करना इसे create करता है, इसलिए test करें k in d के साथ, d[k] के नहीं। `Counter` एक sequence को tally करता है और .most_common(n) pulls करता है top n।

व्यवहार में

एक score tracker को building करना और एक summary को सभी entries के साथ print करना:

python
# सभी स्कोर
scores = {"राज": 87, "प्रिया": 74, "कार्तिक": 92, "दीक्षा": 55}

total = sum(scores.values())
average = total / len(scores)

print(f"खिलाड़ी:  {len(scores)}")
print(f"औसत:  {average:.1f}")
print(f"सर्वोच्च:  {max(scores.values())}")
print(f"न्यूनतम:   {min(scores.values())}")
print()

for name, score in scores.items():
    print(f"  {name}: {score}")

एक dict को per-file results के साथ एक loop में building करना, फिर सभी entries के across summarising:

python
# job परिणाम
job_results = {}
files = ["report_jan.csv", "report_feb.csv", "report_mar.csv"]

for filename in files:
    size = len(filename) * 100   # placeholder for real file size
    if size < 2000:
        status = "ok"
    else:
        status = "large"
    job_results[filename] = {"size": size, "status": status}

ok_count = 0
large_count = 0

for result in job_results.values():
    if result["status"] == "ok":
        ok_count += 1
    else:
        large_count += 1

print(f"Processed {len(job_results)} file(s): {ok_count} ok, {large_count} large")

एक nested request dict को required fields के through iterating करके validate करना, फिर एक feature importance dict को जगह पर normalize करना:

python
# request
request = {
    "method": "POST",
    "path": "/users",
    "headers": {"Content-Type": "application/json"},
    "body": {"username": "राज", "email": "राज@example.com"},
}

body = request["body"]
errors = []

for field in ["username", "email"]:
    if not body.get(field):
        errors.append(f"Missing required field: {field}")

if "email" in body and "@" not in body["email"]:
    errors.append("Invalid email format")

print(f"Method: {request['method']} {request['path']}")
if errors:
    print(f"Errors: {errors}")
else:
    print("Validation passed")

# feature importance values को 1 के लिए normalize करें
feature_importance = {"age": 0.34, "income": 0.28, "region": 0.15, "purchases": 0.23}
total = sum(feature_importance.values())

for key in feature_importance:
    feature_importance[key] = round(feature_importance[key] / total, 3)

print(f"Normalised: {feature_importance}")