# agrupar dades relacionades

Estructures en Python

Python no té struct: un dict ja fa aquesta feina, i de pas serveix per a molt més. I la gestió de memòria... simplement no en calrà parlar.

dict com a struct lleugera

Un diccionari pot agrupar diverses dades sota un sol nom, cadascuna amb la seva clau — exactament el que fa una struct en C.

Exemple

persona = {"nom": "Jordi", "edat": 16}

print(f"{persona['nom']} té {persona['edat']} anys")

On C necessita definir primer una plantilla (struct Persona { ... }) i després crear-ne variables, Python no necessita cap pas previ: el diccionari ja és la dada.

Un dict com a paràmetre

A diferència d'una struct de C (que es copia sencera en passar-la a una funció), un dict és mutable: es comporta com la llista del capítol de referències.

def aniversari(p):
    p["edat"] = p["edat"] + 1
    print(f"Dins: {p['nom']} té {p['edat']} anys")

Aquí sí que el canvi es veurà des de fora un cop torni la funció — just el contrari del que passava amb struct Persona en C. Ho veuràs en detall a l'execució pas a pas.

namedtuple

Quan les claus són sempre les mateixes i vols accedir-hi com si fossin atributs (persona.nom en lloc de persona["nom"]), namedtuple és una alternativa més propera a l'esperit d'una struct.

from collections import namedtuple

Persona = namedtuple("Persona", ["nom", "edat"])
p1 = Persona("Jordi", 16)

print(f"{p1.nom} té {p1.edat} anys")

Com el seu nom indica, és una tupla: immutable, igual que les tuples que ja coneixes. Un cop creada, no se'n pot canviar cap camp.

Gestió de memòria

A C necessitaves malloc per reservar memòria en temps d'execució, i free per alliberar-la tu mateix. En Python no cal fer res de tot això.

n = int(input("Quantes persones? "))
agenda = []

for i in range(n):
    agenda.append({"nom": "...", "edat": 0})

Una llista ja creix tant com calgui, sense haver de dir mai amb quants elements comptar per endavant. I quan un objecte ja no es fa servir enlloc, el recol·lector d'escombraries (garbage collector) de Python l'allibera tot sol — mai hi ha cap free() a escriure, ni cap fuita de memòria per culpa d'oblidar-lo.

bonus Funcions com a valors

C necessita apuntadors a funció per passar "quin codi executar" com a argument. En Python, les funcions ja són valors com qualsevol altre: es passen directament, sense cap sintaxi especial.

def per_preu(llibre):
    return llibre["preu"]

llibres = [{"titol": "A", "preu": 12}, {"titol": "B", "preu": 8}]
llibres_ordenats = sorted(llibres, key=per_preu)

sorted(..., key=per_preu) li passa la funció per_preu mateixa (sense parèntesis: no la crides, la passes) perquè sorted() sàpiga com comparar dos llibres — el mateix paper que feia compara amb qsort() a C, sense necessitat de cap concepte d'"apuntador".

Mira els diccionaris pas a pas

Fixa't en el contrast amb C: aquí, modificar un dict dins d'una funció sí que es veu des de fora.

Estructures

Codi

Variables

NomValor

Terminal

Pas 1 / 1

Problemes per resoldre

Sense solució ni comprovació automàtica: escriu el programa, executa'l (python3 programa.py) i prova'l amb els exemples. Les pistes són plegades perquè les obris només si les necessites.

1. Llista de diccionaris

Fes una llista de 3 diccionaris {"titol": ..., "preu": ...} amb valors escrits al codi. Mostra quin és el més car.

El més car és: El Petit Príncep (18.5)
Pistes

Recorre la llista amb un bucle, comparant llibre["preu"] amb el candidat actual — igual que faries amb una llista de números.

2. Agenda

Demana quantes persones vols desar, i per cadascuna el nom i l'edat; desa-les en una llista de diccionaris i mostra la mitjana d'edat.

Quantes persones? 2
Nom 1: Jordi
Edat 1: 16
Nom 2: Anna
Edat 2: 20
Mitjana d'edat: 18.00
Pistes

Comença amb agenda = [] i ves afegint-hi diccionaris amb agenda.append({"nom": nom, "edat": edat}) — sense cap malloc ni mida que calgui decidir per endavant.

3. Amb namedtuple

Repeteix l'exercici 1 (el llibre més car), però fent servir namedtuple en lloc de diccionaris.

El més car és: El Petit Príncep (18.5)
Pistes

Llibre = namedtuple("Llibre", ["titol", "preu"]), i després Llibre("El Petit Príncep", 18.5) per crear-ne un.

L'accés canvia de llibre["preu"] a llibre.preu — la resta de la lògica és idèntica a l'exercici 1.

Exercicis d'autoavaluació

Aquests es generen amb valors nous a l'atzar i tenen solució comprovable.

—

Quina serà la sortida per terminal d'aquest programa?