Python-இல் அகராதிகள் (dict): உருவாக்கம், முறைகள், சுழல், வரிசைப்படுத்தல் மற்றும் frozendict
Python-இல் அகராதி (dict) என்பது "விசை — மதிப்பு" ஜோடிகளின் மாற்றக்கூடிய தொகுப்பு; விசையின் மூலம் மதிப்பை கிட்டத்தட்ட உடனே கண்டறியலாம். {"காபி": 250} என்ற பிரேஸ்களாலோ dict() செயல்பாட்டாலோ உருவாக்கப்படும். விசைகள் தனித்துவமானவை, ஹாஷ் செய்யக்கூடியவை; Python 3.7 முதல் செருகிய வரிசை பாதுகாக்கப்படுகிறது; Python 3.15-இல் உள்ளமைவு மாற்ற முடியாத வகை frozendict வந்துள்ளது.
Python-இல் அகராதி (dict) என்பது "விசை — மதிப்பு" ஜோடிகளின் தொகுப்பு: பதிவுகள் எத்தனை இருந்தாலும் விசையின் மூலம் மதிப்பை கிட்டத்தட்ட உடனே கண்டறியலாம். வகைவாரியாக செலவுகளைக் கணக்கிட, அமைப்புகளைச் சேமிக்க, பயனரை id மூலம் விரைவாகத் தேட நீங்கள் அகராதியைப் பயன்படுத்துவீர்கள். கீழே python dict-உடன் வேலை செய்ய வேண்டிய அனைத்தும்: உருவாக்கம், முறைகள், சுழல், வரிசைப்படுத்தல், இணைப்பு, மற்றும் Python 3.15-இன் புதுமை — frozendict.
Python-இல் அகராதி என்றால் என்ன
அகராதி ஜோடிகளைச் சேமிக்கிறது; விசை தனித்துவமானது: ஏற்கனவே உள்ள விசைக்கு மதிப்பு எழுதினால் பழையது மாற்றப்படும். உள்ளே அது ஒரு ஹாஷ் அட்டவணை; அதனால் விசையின் மூலம் தேடல், சேர்த்தல், நீக்கல் ஆகியவை சராசரியாக நிலையான நேரத்தில் நடக்கும் — ஒவ்வொன்றாகத் தேடுவதில்லை.
விசை ஹாஷ் செய்யக்கூடிய பொருளாக மட்டுமே இருக்க முடியும்: சரம், எண், மாற்ற முடியாத மதிப்புகளின் tuple. பட்டியலை விசையாகப் பயன்படுத்த முடியாது — TypeError: unhashable type: 'list' வரும். மதிப்புகளோ எதுவாகவும் இருக்கலாம், மற்ற அகராதிகளும் பட்டியல்களும் உட்பட.
Python 3.7 முதல் அகராதி செருகிய வரிசையை உறுதியாக நினைவில் வைக்கிறது: சுற்றும்போது விசைகள் சேர்த்த வரிசையிலேயே வரும்.
அகராதியை எப்படி உருவாக்குவது
அகராதியை உருவாக்க பல வழிகள் உள்ளன; எல்லாமே உண்மையான குறியீட்டில் வருகின்றன.
spent = {"உணவு": 1200, "டாக்ஸி": 450} # literal
empty = {} # வெற்று அகராதி
also_empty = dict() # அதே, dict செயல்பாட்டால்
user = dict(name="அன்னா", age=30) # பெயரிட்ட வாதங்கள்
pairs = dict([("a", 1), ("b", 2)]) # இணைகளின் பட்டியலிலிருந்து
keys = dict.fromkeys(["x", "y"], 0) # {'x': 0, 'y': 0}
கவனியுங்கள்: வெற்றுச் சுருள் பிரேஸ்கள் {} வெற்று அகராதியையே உருவாக்கும், set-ஐ அல்ல. வெற்று set-ஐ set() மூலம் மட்டுமே உருவாக்க முடியும்.
இரண்டு பட்டியல்களிலிருந்து அகராதியைக் கட்ட வசதியான வழி — zip:
names = ["உணவு", "டாக்ஸி", "சினிமா"]
sums = [1200, 450, 600]
spent = dict(zip(names, sums))
print(spent) # {'உணவு': 1200, 'டாக்ஸி': 450, 'சினிமா': 600}
விசையின் மூலம் அணுகுதல்: d[k] மற்றும் get
மதிப்பு சதுர அடைப்புக்குறிகளால் படிக்கப்படும். விசை இல்லையென்றால் Python KeyError வீசும். பிழை வராமல் இருக்க get முறையைப் பயன்படுத்துங்கள்: அது None அல்லது இயல்பு மதிப்பைத் தரும்.
spent = {"உணவு": 1200}
print(spent["உணவு"]) # 1200
print(spent.get("சினிமா")) # None
print(spent.get("சினிமா", 0)) # 0
spent["சினிமா"] # KeyError: 'சினிமா'
அகராதியில் விசை உள்ளதா என்று in இயக்கியால் சரிபார்க்கலாம்: "உணவு" in spent True தரும். அது விசைகளை மட்டுமே சரிபார்க்கும், மதிப்புகளை அல்ல. மதிப்புகளுக்கு 1200 in spent.values() எழுதுங்கள்.
சேர்த்தல், மாற்றுதல் மற்றும் நீக்குதல்
பதிவைச் சேர்க்க அல்லது புதுப்பிக்க ஒரே ஒரு ஒதுக்கல் வரி போதும். எண்ணிக்கைக்கு get உடன் சேர்த்து பயன்படுத்துவது மிகவும் வசதியானது:
spent = {}
for category, amount in [("உணவு", 250), ("டாக்ஸி", 300), ("உணவு", 400)]:
spent[category] = spent.get(category, 0) + amount
print(spent) # {'உணவு': 650, 'டாக்ஸி': 300}
விசையை del d[k] மூலம் நீக்கலாம் (விசை இல்லையென்றால் KeyError), அல்லது மதிப்பையும் திருப்பித் தரும் d.pop(k, default) மூலம். அகராதியை முழுவதுமாக வெறுமையாக்க — d.clear(). அகராதியின் நீளம், அதாவது ஜோடிகளின் எண்ணிக்கை — len(d).
அகராதி முறைகள்: சுருக்கக் குறிப்பு
| முறை | என்ன செய்கிறது |
|---|---|
get(k, default) | விசையின் மதிப்பு, இல்லையென்றால் default — பிழை இல்லாமல் |
setdefault(k, default) | மதிப்பைத் தரும்; விசை இல்லையென்றால் முதலில் default-ஐ எழுதும் |
update(other) | மற்ற அகராதியின் ஜோடிகளைச் சேர்த்து மேலெழுதும் |
pop(k, default) | விசையை நீக்கி மதிப்பைத் திருப்பும் |
popitem() | கடைசியாகச் சேர்த்த ஜோடியை நீக்கித் திருப்பும் |
keys(), values(), items() | விசைகள், மதிப்புகள், ஜோடிகளின் காட்சிகள் |
copy() | மேலோட்ட நகல் |
clear() | அகராதியை வெறுமையாக்கு |
fromkeys(keys, value) | ஒரே மதிப்புடன் புதிய அகராதி |
setdefault: பட்டியல்களால் அகராதியை நிரப்புதல்
மதிப்புகள் பட்டியல்களாக இருந்து தொகுக்க வேண்டியபோது setdefault உதவுகிறது:
groups = {}
for item, cat in [("காபி", "உணவு"), ("மெட்ரோ", "போக்குவரத்து"), ("பிட்சா", "உணவு")]:
groups.setdefault(cat, []).append(item)
print(groups) # {'உணவு': ['காபி', 'பிட்சா'], 'போக்குவரத்து': ['மெட்ரோ']}
update: அகராதியைப் புதுப்பித்தல்
update அகராதியை அதே இடத்தில் மாற்றுகிறது: புதிய விசைகள் சேர்க்கப்படும், பொருந்தும் விசைகள் மேலெழுதப்படும்.
cfg = {"debug": False, "lang": "ta"}
cfg.update({"debug": True, "theme": "dark"})
print(cfg) # {'debug': True, 'lang': 'ta', 'theme': 'dark'}
defaultdict: இயல்பு மதிப்புள்ள அகராதி
collections.defaultdict என்பது dict-இன் துணைவகை: இல்லாத விசையை அணுகும்போது அது ஒரு தொழிற்சாலை மூலம் மதிப்பைத் தானாக உருவாக்கும். எண்ணிக்கை மற்றும் குழுவாக்கல் குறியீடு சுருங்கும்.
from collections import defaultdict
spent = defaultdict(int)
for cat, amount in [("உணவு", 250), ("டாக்ஸி", 300), ("உணவு", 400)]:
spent[cat] += amount
print(dict(spent)) # {'உணவு': 650, 'டாக்ஸி': 300}
groups = defaultdict(list)
groups["உணவு"].append("காபி")
எளிய எண்ணிக்கைக்கு collections.Counter-உம் உண்டு: Counter(["a", "b", "a"]) Counter({'a': 2, 'b': 1}) தரும்.
அகராதியில் சுழல்: for சுழல்
for சுழலில் அகராதியின் மீது சுற்றும்போது இயல்பாக விசைகள் வரும். விசையும் மதிப்பும் ஒன்றாகப் பெற items() மீது சுற்றுங்கள் — மிகவும் பொதுவான வழி.
spent = {"உணவு": 650, "டாக்ஸி": 300}
for cat in spent: # விசைகள்
print(cat)
for amount in spent.values(): # மதிப்புகள்
print(amount)
for cat, amount in spent.items(): # ஜோடிகள்
print(f"{cat}: {amount} ₹")
சுழல் நடக்கும்போதே அகராதியின் அளவை மாற்றக்கூடாது — RuntimeError: dictionary changed size during iteration வரும். சில விசைகளை நீக்க வேண்டுமெனில் நகலின் மீது சுற்றுங்கள்: for k in list(d):.
அகராதியை திரையில் காட்டுதல்
print(d) அகராதியை ஒரே வரியில் அச்சிடும். பெரிய அல்லது உள்ளமை அகராதிக்கு pprint தொகுதி அல்லது json.dumps(d, ensure_ascii=False, indent=2) வசதியானது — அவை தரவை உள்தள்ளல்களுடனும் தமிழ் எழுத்துகளைத் தப்பிக்காமலும் காட்டும்.
அகராதியை வரிசைப்படுத்துதல்
அகராதியை அதே இடத்தில் வரிசைப்படுத்த முடியாது; அதற்கு sort முறை இல்லை. அகராதியின் வரிசைப்படுத்தல் என்பது sorted மூலம் வரிசைப்படுத்திய ஜோடிகளிலிருந்து புதிய அகராதியை உருவாக்குவது.
spent = {"டாக்ஸி": 300, "உணவு": 650, "சினிமா": 120}
by_key = dict(sorted(spent.items()))
print(by_key) # {'உணவு': 650, 'சினிமா': 120, 'டாக்ஸி': 300}
by_value = dict(sorted(spent.items(), key=lambda p: p[1], reverse=True))
print(by_value) # {'உணவு': 650, 'டாக்ஸி': 300, 'சினிமா': 120}
சிறந்த N வகைகள் மட்டும் தேவை என்றால் முடிவை மீண்டும் அகராதியாக்க வேண்டாம்: sorted(spent.items(), key=lambda p: p[1], reverse=True)[:2] ஜோடிகளின் பட்டியலைத் தரும்.
அகராதிகளின் பட்டியலை ஒரு புலத்தால் வரிசைப்படுத்த: sorted(users, key=lambda u: u["age"]).
அகராதிகளை இணைத்தல் மற்றும் கூட்டுதல்
Python 3.9 முதல் அகராதிகள் | இயக்கியால் இணைகின்றன; |= அதே இடத்தில் புதுப்பிக்கும். விசைகள் பொருந்தினால் வலது பக்க மதிப்பு வெல்லும்.
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
print(a | b) # {'x': 1, 'y': 20, 'z': 3}
print({**a, **b}) # அதே, unpacking வழியாக
a |= b # a.update(b) போல
கவனியுங்கள்: அகராதிகளுக்கு a + b வேலை செய்யாது, TypeError வரும். ஒரே விசைகளின் மதிப்புகளைக் கூட்ட வேண்டுமெனில் Counter பயன்படுத்துங்கள்: Counter(a) + Counter(b).
அகராதியின் unpacking
இரண்டு நட்சத்திரக்குறிகள் ** அகராதியைச் செயல்பாட்டின் பெயரிட்ட வாதங்களாக அல்லது மற்றொரு அகராதியாக விரிக்கும்:
def greet(name, city):
return f"{name}, {city} இலிருந்து"
data = {"name": "அன்னா", "city": "சென்னை"}
print(greet(**data)) # அன்னா, சென்னை இலிருந்து
அகராதி உருவாக்கல் (dict comprehension)
அகராதி உருவாக்கல் எந்த வரிசையிலிருந்தும் ஒரே வரியில் அகராதியைக் கட்டும்:
squares = {n: n * n for n in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
big = {k: v for k, v in spent.items() if v > 200}
inverted = {v: k for k, v in {"a": 1, "b": 2}.items()}
print(inverted) # {1: 'a', 2: 'b'}
கடைசி எடுத்துக்காட்டு அகராதியைத் தலைகீழாக்குவது எப்படி என்று காட்டுகிறது — விசைகளையும் மதிப்புகளையும் மாற்றி. மதிப்புகள் தனித்துவமாகவும் ஹாஷ் செய்யக்கூடியதாகவும் இருந்தால் மட்டுமே இது வேலை செய்யும்; இல்லையென்றால் சில ஜோடிகள் இழக்கப்படும்.
உள்ளமை அகராதிகள்
மதிப்பு மற்றொரு அகராதியாக இருக்கலாம் — API பதில்கள் போன்ற JSON கட்டமைப்புகளையும், பயனர்களின் அகராதி-அகராதிகளையும் இப்படித்தான் விவரிக்கிறோம்.
users = {
101: {"name": "அன்னா", "skills": ["python", "sql"]},
102: {"name": "ஓலெக்", "skills": ["go"]},
}
print(users[101]["skills"][0]) # python
print(users.get(103, {}).get("name")) # None, KeyError இல்லாமல்
அகராதியை நகலெடுத்தல்: நகல் மற்றும் இரண்டாம் பெயர்
b = a அகராதியை நகலெடுக்காது; அதே பொருளுக்கு இரண்டாவது பெயரைத் தருகிறது. b வழியாக மாற்றினால் a-விலும் தெரியும். அகராதியைச் செயல்பாட்டுக்கு அனுப்பும்போதும் இதே நடக்கும்: அது பகிரப்பட்ட பொருளின் குறிப்பைப் பெறுகிறது, அதை அமைதியாகக் கெடுக்கலாம்.
import copy
a = {"limits": [0, 500]}
b = a.copy() # மேலோட்ட நகல்
b["limits"].append(1000) # உள் பட்டியல் பகிரப்பட்டது!
print(a) # {'limits': [0, 500, 1000]}
c = copy.deepcopy(a) # முழுமையாகச் சுயாதீன நகல்
அகராதிகளை ஒப்பிடுதல்
== அகராதிகளை உள்ளடக்கத்தால் ஒப்பிடும்: எல்லா ஜோடிகளும் பொருந்தினால் சமம். விசைகளின் வரிசை கணக்கில் கொள்ளப்படாது: {"a": 1, "b": 2} == {"b": 2, "a": 1} True தரும். பொதுவான விசைகளைக் கண்டறிய காட்சிகளின் மீது set செயல்பாடுகளைப் பயன்படுத்துங்கள்: a.keys() & b.keys().
வகையுடன் கூடிய அகராதி: annotations
அகராதியின் annotation dict[str, int] போல எழுதப்படுகிறது. அகராதிக்கு வெவ்வேறு வகைப் புலங்களின் நிலையான தொகுப்பு இருந்தால், typing தொகுதியின் TypedDict வசதியானது:
from typing import TypedDict
class User(TypedDict):
name: str
age: int
u: User = {"name": "அன்னா", "age": 30}
Annotations இயக்க நேரத்தில் சரிபார்க்கப்படுவதில்லை; அவற்றை IDE-களும் mypy போன்ற பகுப்பாய்வாளர்களும் படிக்கின்றன.
மாற்ற முடியாத அகராதி: Python 3.15-இல் frozendict
Python 3.15-இல் frozendict என்ற உள்ளமைவு வகை வந்தது (PEP 814): இறக்குமதி தேவையில்லை, மாற்ற முயன்றால் உடனே TypeError வரும். முன்பு மாற்ற முடியாத அகராதியை types தொகுதி மூலம் அல்லது மூன்றாம் தரப்புத் தொகுப்பின் மூலம்தான் செய்ய வேண்டியிருந்தது. பொதுவான அமைப்புகளுக்கு இதுவே தேவை — எந்தச் செயல்பாடும் அமைதியாக மாற்றக்கூடாத அமைப்புகள்.
config = frozendict(min_amount=0, max_amount=500)
config["max_amount"] = 1000
# TypeError: 'frozendict' object does not support item assignment
strict = config | {"max_amount": 300} # புதிய frozendict, மூலம் அப்படியே
cache = {config: "மே மாத அறிக்கை"} # ஹாஷ் செய்யக்கூடியது — விசையாகப் பயன்படும்
பாடநெறிப் பொருட்களின்படி அறிய வேண்டியவை:
frozendictobject-இலிருந்து மரபுரிமை பெறுகிறது,dict-இலிருந்து அல்ல; அதனால்isinstance(cfg, dict)Falseதரும். "எந்த அகராதியும்" என்று சரிபார்க்கcollections.abc.Mappingஅல்லதுisinstance(x, (dict, frozendict))பயன்படுத்துங்கள்.- விசைகளும் மதிப்புகளும் ஹாஷ் செய்யக்கூடியவையாக இருந்தால் மட்டுமே அது ஹாஷ் செய்யக்கூடியது:
frozendict(a=[1])உருவாகும், ஆனால்hash()தோல்வியடையும். மாற்ற முடியாமை ஆழமற்றது, tuple போன்றது. - வரிசை சேமிக்கப்படுகிறது, ஆனால்
==அதைக் கணக்கில் கொள்ளாது. json.dumps,pickleமற்றும்copyfrozendict-ஐப் புரிந்துகொள்ளும்.
பொதுவான தவறுகள்
- KeyError படிக்கும்போது —
getஅல்லதுinசரிபார்ப்பைப் பயன்படுத்துங்கள். - பட்டியலை விசையாகப் பயன்படுத்துவது — அதை tuple ஆக்குங்கள்:
d[tuple(lst)]. - சுழலில் அகராதியை மாற்றுவது —
list(d)மீது சுற்றுங்கள். - ஒதுக்கலிலிருந்து நகல் எதிர்பார்ப்பது —
copy()அல்லதுdeepcopyசெய்யுங்கள். - வெற்று set-க்குப் பதிலாக
{}— அது வெற்று அகராதி.
சுருக்கம்
Python dict என்பது மொழியின் முக்கிய தரவு அமைப்பு: விசையின் மூலம் வேகமான தேடல், பாதுகாக்கப்படும் செருகு வரிசை, get, setdefault, update போன்ற வசதியான முறைகள், items() வழியாகச் சுற்றுதல், sorted மூலம் வரிசைப்படுத்தல், | இயக்கியால் இணைப்பு. நகலெடுத்தல் மற்றும் ஹாஷ் செய்யக்கூடிய விசைகள் குறித்து கவனமாக இருங்கள்; Python 3.15-இல் அமைப்புகளுக்கு frozendict-ஐ எடுங்கள். அகராதிகள், பட்டியல்கள், tuple-கள் மற்றும் set-கள் «Python 3.15: பூஜ்ஜியத்திலிருந்து நிபுணர் வரை» பாடநெறியில் செலவு கண்காணிப்பானின் எடுத்துக்காட்டில் நடைமுறையில் விளக்கப்பட்டுள்ளன.
அடிக்கடி கேட்கப்படும் கேள்விகள்
அகராதியில் வெவ்வேறு வகை மதிப்புகளை வைக்க முடியுமா?
ஆம், மதிப்புகள் எதுவாகவும் இருக்கலாம், ஒரே அகராதியில் வெவ்வேறாகவும் இருக்கலாம்: எண்கள், சரங்கள், பட்டியல்கள், மற்ற அகராதிகள். கட்டுப்பாடு விசைகளுக்கு மட்டுமே — அவை ஹாஷ் செய்யக்கூடியதாக இருக்க வேண்டும்.
அகராதியில் எத்தனை உறுப்புகள் உள்ளன என்று எப்படி அறிவது?
<code>len(d)</code> விசை — மதிப்பு ஜோடிகளின் எண்ணிக்கையைத் தரும். வெற்று அகராதிக்கு அது 0; <code>if</code> நிபந்தனையில் வெற்று அகராதி பொய்யாகக் கருதப்படும்.
dict மற்றும் defaultdict இடையே வேறுபாடு என்ன?
defaultdict என்பது dict-இன் துணைவகை; இல்லாத விசையை அணுகும்போது KeyError வீசாமல், <code>int</code> அல்லது <code>list</code> போன்ற தொழிற்சாலை மூலம் மதிப்பை உருவாக்கும். மற்றபடி அது சாதாரண அகராதியைப் போலவே நடந்துகொள்ளும்.
மதிப்பை வைத்து விசையை எப்படிப் பெறுவது?
நேரடி முறை இல்லை; சுற்ற வேண்டும்: <code>next((k for k, v in d.items() if v == value), None)</code>. இதை அடிக்கடி தேடினால் <code>{v: k for k, v in d.items()}</code> என்ற தலைகீழ் அகராதியைக் கட்டுவது எளிது.
அகராதியை கோப்பில் எப்படிச் சேமிப்பது?
பெரும்பாலும் <code>json</code> தொகுதி மூலம்: எழுதும் திறந்த கோப்பில் <code>json.dump(d, f, ensure_ascii=False, indent=2)</code>, படிக்க <code>json.load(f)</code>. அப்போது விசைகள் சரங்களாக மாறும்.
“Python 3.15: от новичка до профи” பாடநெறியில் இந்தத் தலைப்பு பயிற்சியுடன் விரிவாக விளக்கப்பட்டுள்ளது.
பாடநெறிக்குச் செல்