# Python-இல் அகராதிகள் (dict): உருவாக்கம், முறைகள், சுழல், வரிசைப்படுத்தல் மற்றும் frozendict

URL: https://skillaria.top/ta/guides/python/slovari-python

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: "மே மாத அறிக்கை"}        # ஹாஷ் செய்யக்கூடியது — விசையாகப் பயன்படும்
```

பாடநெறிப் பொருட்களின்படி அறிய வேண்டியவை:

- `frozendict` `object`-இலிருந்து மரபுரிமை பெறுகிறது, `dict`-இலிருந்து அல்ல; அதனால் `isinstance(cfg, dict)` `False` தரும். "எந்த அகராதியும்" என்று சரிபார்க்க `collections.abc.Mapping` அல்லது `isinstance(x, (dict, frozendict))` பயன்படுத்துங்கள்.
- விசைகளும் மதிப்புகளும் ஹாஷ் செய்யக்கூடியவையாக இருந்தால் மட்டுமே அது ஹாஷ் செய்யக்கூடியது: `frozendict(a=[1])` உருவாகும், ஆனால் `hash()` தோல்வியடையும். மாற்ற முடியாமை ஆழமற்றது, tuple போன்றது.
- வரிசை சேமிக்கப்படுகிறது, ஆனால் `==` அதைக் கணக்கில் கொள்ளாது.
- `json.dumps`, `pickle` மற்றும் `copy` frozendict-ஐப் புரிந்துகொள்ளும்.

## பொதுவான தவறுகள்

- **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: பூஜ்ஜியத்திலிருந்து நிபுணர் வரை» பாடநெறியில் செலவு கண்காணிப்பானின் எடுத்துக்காட்டில் நடைமுறையில் விளக்கப்பட்டுள்ளன.

## FAQ

**அகராதியில் வெவ்வேறு வகை மதிப்புகளை வைக்க முடியுமா?**

ஆம், மதிப்புகள் எதுவாகவும் இருக்கலாம், ஒரே அகராதியில் வெவ்வேறாகவும் இருக்கலாம்: எண்கள், சரங்கள், பட்டியல்கள், மற்ற அகராதிகள். கட்டுப்பாடு விசைகளுக்கு மட்டுமே — அவை ஹாஷ் செய்யக்கூடியதாக இருக்க வேண்டும்.

**அகராதியில் எத்தனை உறுப்புகள் உள்ளன என்று எப்படி அறிவது?**

len(d) விசை — மதிப்பு ஜோடிகளின் எண்ணிக்கையைத் தரும். வெற்று அகராதிக்கு அது 0; if நிபந்தனையில் வெற்று அகராதி பொய்யாகக் கருதப்படும்.

**dict மற்றும் defaultdict இடையே வேறுபாடு என்ன?**

defaultdict என்பது dict-இன் துணைவகை; இல்லாத விசையை அணுகும்போது KeyError வீசாமல், int அல்லது list போன்ற தொழிற்சாலை மூலம் மதிப்பை உருவாக்கும். மற்றபடி அது சாதாரண அகராதியைப் போலவே நடந்துகொள்ளும்.

**மதிப்பை வைத்து விசையை எப்படிப் பெறுவது?**

நேரடி முறை இல்லை; சுற்ற வேண்டும்: next((k for k, v in d.items() if v == value), None). இதை அடிக்கடி தேடினால் {v: k for k, v in d.items()} என்ற தலைகீழ் அகராதியைக் கட்டுவது எளிது.

**அகராதியை கோப்பில் எப்படிச் சேமிப்பது?**

பெரும்பாலும் json தொகுதி மூலம்: எழுதும் திறந்த கோப்பில் json.dump(d, f, ensure_ascii=False, indent=2), படிக்க json.load(f). அப்போது விசைகள் சரங்களாக மாறும்.


---
Source: Skillaria.Top (https://skillaria.top)
