=========================== Algorismes sobre seqüències =========================== Llistes per comprensió ====================== - Una :term:`llista per comprensió` és una sintaxi compacta per calcular una llista processant tots o part dels elements d’una term:`seqüència` - La notació s'inspira en la de `construcció de conjunts `__ - Exemples - Llista amb els nombres d'una altra llista en valor absolut >>> nombres = [-15, 9, 2, -5, -8, 4] >>> nombres_abs = [abs(n) for n in nombres] >>> nombres_abs [15, 9, 2, 5, 8, 4] - Llista amb els nombres parells d'una seqüència elevats al quadrat >>> a = 7, -1, 4, 5, 2, -6 >>> b = [x**2 for x in a if x%2 == 0] >>> b [16, 4, 36] Recorregut dels elements d'una seqüència ======================================== - La sentència ``for`` permet recórrer els elements d'una seqüència i executar les sentències per cada un d'ells .. code-block:: python3 for element in seqüència: sentències - ``element`` és una variable - ``seqüència`` és una expressió que s'avalua a una :term:`seqüència` - ``sentències`` són un bloc de sentències sagnades respecte de la capçalera - :term:`Iterar ` és repetir l'execució d'un bloc de codi - Com que la sentència ``for`` permet iterar direm que és una (sentència d'iteració) - També diem iteració a l'execució de les ``sentències`` per un concret d\'``element`` - :term:`Esquemes ` - :term:`recorregut `: :term:`aplica `, :term:`filtra ` i :term:`sintetitza ` - :term:`cerca ` Recorreguts per generar llistes =============================== Esquema aplica -------------- Genera una llista a partir d'una seqüència en què cada element de la llista es calcula aplicant (cridant) una funció sobre l'element corresponent de la seqüència. Per exemple: - :doc:`fi:temes/llistes_i_tuples/Vectors/index` 3. - :doc:`fi:temes/llistes_i_tuples/Aplicar_prefix/index` 1. L'esquema general és .. code-block:: python3 def aplica(seqüència, funció): r = [] for elem in seqüència: elem_r = funció(elem) r.append(elem_r) return r on només cal decidir #. quina és la funció que cal aplicar a cada element (:code:`funció`). Les :term:`llistes per comprensió ` permeten obtenir el mateix resultat: .. code-block:: python3 r = [funció(elem) for elem in seqüència] Esquema Filtra -------------- Genera una llista que conté els elements de la seqüència que compleixen una condició. Per exemple: - calcular la llista dels nombres positius - :doc:`fi:temes/llistes_i_tuples/Pessetes/index` 4 - :doc:`fi:temes/llistes_i_tuples/Positius_i_negatius/index` 2 L'esquema general és .. code-block:: python3 def filtra(seqüència, condició): r = [] for elem in seqüència: if condició(elem): r.append(elem) return r on només cal decidir #. quina és la condició que han de complir els elements triats (:code:`condició`). Les llistes per comprensió permeten obtenir el mateix resultat: .. code-block:: python3 r = [elem for elem in seqüència if condició(elem)] Recorregut per sintetitzar ========================== Calcula un resultat que *sintetitza* els valors dels elements de la seqüència. Per exemple: - sumar els elements (:py:func:`sum`), - calcular el màxim (:py:func:`max`) o el mínim (:py:func:`min`), - comptar els elements (:func:`len`), - concatenar els elements d'una llista d\'*strings* (:py:meth:`str.join`). - :doc:`fi:temes/llistes_i_tuples/Mesures/index`, mitjana L'esquema general és .. code-block:: python3 def sintetiza(seqüència, acumula, element_neutre_acumula): s = element_neutre_acumula for elem in seqüència: s = acumula(s, elem) return s on només cal decidir #. quina és l'operació :code:`acumula`, i #. quin és l'element neutre d'aquesta operació (:code:`element_neutre_acumula`) Cercar en una seqüència ======================= Decidir si algun dels elements d'una seqüència compleix una condició. Per exemple: - :doc:`fi:temes/llistes_i_tuples/Cercant_en_llistes/index` 1 - :doc:`fi:temes/llistes_i_tuples/Vectors/index` 2 L'esquema general és .. code-block:: python3 def cerca(seqüència, condició): trobat = False for elem in seqüència: trobat = condició(elem) if trobat: break return trobat on només cal decidir #. quina és la condició que ha de complir l'element que busquem (:code:`condició`). Combinacions d'esquemes ======================= - Qualsevol combinació de sintetitza, aplica, filtra i cerca. - Les llistes per compressió combinen els esquemes de filtra i aplica: .. code-block:: python3 r = [funció(elem) for elem in seqüència if condició(elem)] - Exemples: - Aplica i sintetitza: :doc:`fi:temes/llistes_i_tuples/Vectors/index`, 1 - Filtra i sintetitza: :doc:`fi:temes/llistes_i_tuples/Strings_i_llistes:_conversió,_split,_join/index`, 7 Recorregut en paral·lel ======================= - Recorregut dels elements de dues o més :term:`seqüències ` en paral·lel - Per exemple: - :doc:`fi:temes/llistes_i_tuples/Vectors/index`, 4 i 5 - La funció :func:`zip` agrupa en una tupla els elements de la mateixa posició de dues o més seqüències >>> seq_a = ['m', 'x', 'r'] >>> seq_b = [7, 3, 5] >>> r = [] >>> for a, b in zip(seq_a, seq_b): ... r.append(a*b) >>> ', '.join(r) 'mmmmmmm, xxx, rrrrr' El tipus :py:class:`range` ========================== - :code:`range(a, b, d)` retorna un objecte de tipus :py:class:`range` que representa els elements de la `progressió aritmètica `__ :math:`a + nd` per :math:`n \ge 0` que són més petits que :math:`b` >>> r = range(3, 10, 2) >>> list(r) [3, 5, 7, 9] - El tipus :class:`range` és un tipus seqüència: admet les :ref:`seq-ops-comunes` i la :ref:`seq-conversions` - Els objectes de tipus :class:`range` són immutables - :code:`d` es pot ometre: :code:`range(a, b)` equival a :code:`range(a, b, 1)` >>> r = range(5, 8) >>> list(r) [5, 6, 7] >>> s = range(5, 8, 1) >>> list(s) [5, 6, 7] - :code:`a` també es pot ometre: :code:`range(b)` equival a :code:`range(0, b, 1)` >>> r = range(5) >>> list(r) [0, 1, 2, 3, 4] >>> s = range(0, 5, 1) >>> list(s) [0, 1, 2, 3, 4] - :code:`d` pot ser negatiu. Aleshores ``a > b`` >>> r = range(8, 3, -1) >>> list(r) [8, 7, 6, 5, 4] .. _recorregut-index: Recorregut dels índexs d'una seqüència ====================================== - Usant ``for`` i :class:`range` .. code-block:: python3 for índex in range(len(seqüència)): sentències - Usant ``for`` i :func:`enumerate` .. code-block:: python3 for índex, element in enumerate(seqüència): sentències Quan cal recórrer els índexs? ----------------------------- - Quan el resultat és un índex (o posició) - índex del primer nombre negatiu - Quan cal modificar algun element de la llista - :doc:`fi:temes/llistes_i_tuples/Intercanviar_màxim_per_mínim/index` - Quan cal desplaçar finestres - :doc:`fi:temes/llistes_i_tuples/Telèfons/index`: 2 Seqüències imbricades ===================== - :term:`Seqüència imbricada`: seqüència en què almenys un dels seus elements és una altra seqüència - Exemples d'accés - L'operador claudàtor s'avalua d'esquerra a dreta - Exemples: - :doc:`fi:temes/llistes_i_tuples/Cinc_al_dia/index`: 1, 3 - :doc:`fi:temes/llistes_i_tuples/Daus/index`: 2, 3 Matrius ------- - Les llistes imbricades es poden usar per representar matrius >>> matrix = [ ... [1, 2, 3], ... [4, 5, 6], ... [7, 8, 9] ... ] >>> matrix[1] [4, 5, 6] >>> matrix[1][1] 5 .. attention:: En crear una matriu, cal garantir que cada fila és una llista diferent. Vegeu :ref:`python:faq-multidimensional-list`. Ordenar ======= Generar una llista ordenada --------------------------- - La funció :py:func:`sorted` **retorna** una llista ordenada que conté els elements d'una seqüència >>> t = (7, 3, 5, 1, 4) >>> l = sorted(t) >>> l [1, 3, 4, 5, 7] - Exemples - :doc:`fi:temes/llistes_i_tuples/Notes/index`: 7 Ordenar una llista ------------------ - El mètode :meth:`~list.sort` reordena els elements de la llista per tal que quedi ordenada. Per tant, **modifica** la llista >>> l = [7, 3, 5, 1, 4] >>> l.sort() >>> l [1, 3, 4, 5, 7] - Exemples - :doc:`fi:temes/llistes_i_tuples/Daus/index`: 4 - :doc:`fi:temes/llistes_i_tuples/Despeses/index` Ordenar decreixentment, paràmetre :code:`reverse` ------------------------------------------------- - El mètode :py:meth:`~list.sort` de llistes i la funció :py:func:`sorted` tenen un paràmetre opcional booleà :code:`reverse` que per defecte val :code:`False` - Si :code:`reverse` és :code:`False`, ordena creixentment - Si :code:`reverse` és :code:`True`, ordena decreixentment - Exemples - :doc:`fi:temes/llistes_i_tuples/Competicio/index` - :doc:`fi:examens/curs2024-2025/2/reava/2/missatges`: 2 El paràmetre :code:`key` ------------------------ - El mètode :py:meth:`~list.sort` de llistes i les funcions :py:func:`sorted`, :py:func:`min` i :py:func:`max` tenen un paràmetre opcional :code:`key` - El paràmetre opcional :code:`key` és útil quan cal comparar els elements de la llista per un criteri diferent de l'ordre estàndard - Exemples - Donada una llista d'strings ordenar-la per la longitud dels strings en comptes de per ordre lexicogràfic >>> ls = ['lluna', 'estrella', 'sol'] >>> ls.sort(key=len) >>> ls ['sol', 'lluna', 'estrella'] - :doc:`fi:temes/llistes_i_tuples/Notes/index`: 8 - :doc:`fi:temes/llistes_i_tuples/Tarifa_plana/index`: 7 - :doc:`fi:examens/curs2022-2023/2/L2/natacio`: 2 Expressions lambda ------------------ Vegeu :ref:`python:lambda` - Permeten escriure funcions anònimes molt senzilles d'una manera sintètica - Sovint s'usen com a arguments de funcions, per exemple, del paràmetre :code:`key` >>> temps = ['9:15', '09:27', '05:07', '5:4'] >>> sorted(temps, key=lambda t: [int(c) for c in t.split(':')]) ['5:4', '05:07', '9:15', '09:27']