=========== Diccionaris =========== Què son? -------- Els *diccionaris* - són objectes de :term:`tipus` :class:`dict` - són :term:`objectes mutables ` - són un `tipus associatiu `__ predefinit de Python Un *tipus associatiu* associa un *valor* a una :term:`clau` - les claus són un conjunt finit i no es repeteixen - el mateix valor pot estar associat a dues claus diferents - correspon al concepte matemàtic d'aplicació o funció Les *claus* d'un diccionari - han de ser de tipus immutables - i si són contenidors (tuples, per exemple), els seus elements també han de ser immutables Com es construeixen? -------------------- - Un :term:`fi:valor literal` de tipus :type:`dict` és una llista de parelles clau-valor separades per comes (``,``) i escrites entre claus (``{}``) - En una parella clau-valor, la clau es separa del valor per dos punts (``:``) - Exemples >>> eng2cat = {'two': 'dos', 'one': 'un', 'three' : 'tres'} >>> eng2cat {'two': 'dos', 'one': 'un', 'three': 'tres'} Operacions de consulta ---------------------- - Longitud: quantes parells clau-valor té el diccionari? >>> len(eng2cat) 3 - Pertinença (``in``, ``not in``): la clau pertany al diccionari? >>> 'two' in eng2cat True - Accés per clau, :term:`mètode` :meth:`~dict.get`: quin és el valor associat a una clau? >>> eng2cat['two'] 'dos' >>> eng2cat[2] Traceback (most recent call last): File "", line 1, in eng2cat[2] ~~~~~~~^^^ KeyError: 2 >>> eng2cat.get('two', '') 'dos' >>> eng2cat.get(2, '') '' >>> valor_per_defecte = '' >>> clau = 2 >>> if clau in eng2cat: ... valor = eng2cat[clau] ... else: ... valor = valor_per_defecte >>> valor '' - Igualtat (``==``, ``!=``): tenen les mateixes parelles clau-valor? >>> d1 = {'un': 1, 'dos': 2} >>> d1 == {'dos': 2, 'un': 1} True >>> d1 == {'un': 'one', 'dos': 'two'} False >>> d1 == {'one': 1, 'two': 2} False - :term:`Funcions predefinides ` (:func:`max`, :func:`min`): quina és la clau més gran (més petita)? >>> max(eng2cat) 'two' >>> min(eng2cat) 'one' Vistes ------ - Claus, valors i parelles clau-valor >>> vk = eng2cat.keys() >>> vk dict_keys(['two', 'one', 'three']) >>> vv = eng2cat.values() >>> vv dict_values(['dos', 'un', 'tres']) >>> vi = eng2cat.items() >>> vi dict_items([('two', 'dos'), ('one', 'un'), ('three', 'tres')]) Conversió de tipus ------------------ - Seqüència de les claus, els valors o les parelles clau-valor >>> d = {1: 'u', 'dos': 2} >>> d_k = d.keys() >>> d_v = d.values() >>> d_i = d.items() >>> list(d) [1, 'dos'] >>> tuple(d_k) (1, 'dos') >>> list(d_v) ['u', 2] >>> list(d_i) [(1, 'u'), ('dos', 2)] - Diccionari a partir d'una seqüència de parelles clau-valor >>> l = [('a', 3), ('b', 9), ('c', 5)] >>> dict(l) {'a': 3, 'b': 9, 'c': 5} Mutabilitat ----------- - Els *diccionaris* són :term:`objectes mutables ` - Tenen operacions per afegir, modificar i esborrar parelles clau-valor Operacions modificadores ------------------------ - Afegir una parella clau-valor >>> 'four' in eng2cat False >>> eng2cat['four'] = 'quatre' >>> eng2cat {'two': 'dos', 'one': 'un', 'three': 'tres', 'four': 'quatre'} >>> vk dict_keys(['two', 'one', 'three', 'four']) >>> vv dict_values(['dos', 'un', 'tres', 'quatre']) >>> vi dict_items([('two', 'dos'), ('one', 'un'), ('three', 'tres'), ('four', 'quatre')]) - Modificar el valor associat a una clau >>> 'two' in eng2cat True >>> eng2cat['two'] = 2 >>> eng2cat {'two': 2, 'one': 'un', 'three': 'tres', 'four': 'quatre'} - Esborrar una parella clau-valor >>> del eng2cat['two'] >>> eng2cat {'one': 'un', 'three': 'tres', 'four': 'quatre'} Generació de diccionaris ------------------------ - A partir d'un diccionari buit >>> polinomi = {} # p(x) = 0 - Afegint parelles clau-valor >>> polinomi[5] = 3 # p(x) = 3x⁵ >>> polinomi[0] = -1 # p(x) = 3x⁵ - 1 >>> polinomi {5: 3, 0: -1} Iteració de diccionaris ----------------------- - Els diccionaris són :term:`iterables ` (com les :term:`seqüències `) >>> for clau in eng2cat: ... print(clau) one three four - Les vistes d'un diccionari també són iterables >>> for clau in vk: ... print(clau) one three four >>> for valor in vv: ... print(valor) un tres quatre >>> for clau, valor in vi: ... print(clau, valor) one un three tres four quatre Algorismes sobre diccionaris ---------------------------- - Els diccionaris són :term:`iterables `, com les :term:`seqüències ` - Els :doc:`/algorismes/index` són :term:`algorismes ` sobre iterables: els :term:`esquemes ` de :term:`recorregut ` i l\':term:`esquema de cerca` serveixen per als diccionaris - El :ref:`recorregut-index` no és útil per als diccionaris Diccionaris per comprensió -------------------------- - Un :term:`diccionari per comprensió` és una sintaxi compacta per calcular un diccionari a partir dels elements d’un :term:`iterable` o només d'una part. - Exemples - Diccionari dels nombres parells d'un iterable i dels seus quadrat >>> nombres = [5, 2, 7, 3, 8, 1, 6] >>> pq = {n: n**2 for n in nombres if n%2 == 0} >>> pq {2: 4, 8: 64, 6: 36} - Diccionari de vocals i valors associats iguals a zero >>> dv = {v: 0 for v in 'aeiou'} >>> dv {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0} Diccionaris imbricats --------------------- Qualsevol combinació de diccionaris i seqüències és vàlida - diccionaris de diccionaris >>> dd = { ... 'Joan': {'casa': '936 513 792', 'mòbil': '732 864 715'}, ... 'Anna': {'feina': '934 902 865'} ... } - diccionaris de llistes >>> dl = { ... 'Maria': [8.4, 10, 7.3], ... 'Pere': [5.7, 4.2] ... } - llistes de diccionaris >>> ld = [ ... {'codi': 'XZ-3', 'preu': 35.7, 'iva': 21}, ... {'codi': 'TW-45', 'preu': 12.83, 'iva': 10, 'estoc': 51} ... ] Còpies ------ - Mètode :py:meth:`~dict.copy`: com obtenir una :term:`còpia ` superficial d'un diccionari? >>> opposites = {'up': 'down', 'right': 'wrong', 'true': 'false'} >>> copia = opposites.copy() >>> copia is opposites False >>> copia == opposites True >>> mateix = opposites >>> mateix is opposites True Exercicis --------- - Creació de diccionaris: :py:doc:`fi:temes/diccionaris/Aparicions_de_lletres/index`. - Les claus són tuples: :py:doc:`fi:temes/diccionaris/Estudiants/index`. - Funcions modificadores de diccionaris: :py:doc:`fi:temes/diccionaris/Botiga_de_roba/index` 1. - Els valors són llistes: :py:doc:`fi:temes/diccionaris/Coral_1/index` 1. - Relació de dos diccionaris: :py:func:`candidats.vots_ingressos`, :py:func:`candidats.rics`, :py:doc:`fi:temes/diccionaris/Coral_1/index` 2. - Recorregut de les parelles clau-valor: :py:func:`candidats.can_mes_votat`. .. :py:doc:`fi:temes/diccionaris/Directius/index` 2. - Recorregut dels valors: :py:func:`candidats.vots_minim`.