Python - Llista

Una llista és un conjunt d'elements agrupats un a continuació de l'altre.

Introducció

Processar llistes d’elements (nombres enters, reals, textos…) agrupats un darrere l’altra és molt habitual.

Crea un project py-list amb uv

Terminal window
uv init py-list

Obre el projecte amb Python - PyCharm

Llista

Python té una estructura de dades de tipus list que es fa servir per guardar elements que en una llista.

Imagina’t que vols guardar la temperatura de Barcelona dels últims 5 dies (mesurat a les 11 del matí).

Amb el que saps fins ara ho pots fer d’aquesta manera:

t0 = 23.5
t1 = 25.5
t2 = 21.2
t3 = 27.4
t4 = 25.5

A continuació, calcula la mitja de la temperatura dels últims 5 dies:

medium = (t0 + t1 + t2 + t3 + t4) / 5
print(f"{medium:.2f}")
24.62

En lloc d’utilitzar una variable per cada element, pots utilitzar una llista per guardar de manera flexible aquestes temperatures i qualsevol altra temperatura que vulguis afegir.

ts = [ 23.5, 25.5, 21.2, 27.4, 25.5 ]
23.525.521.227.425.5

Pots accedir als diferents elements de la llista mitjançant [index], on índex és la posició de l’element dins de la llista començant a contar des del zero.

Per exemple, pots accedir al segon element de la llista amb l’index 1

assert ts[1] == 25.5
23.525.521.227.425.5
Activitat

Calcula la mitja de les temperatures de Barcelona utilitzant la llista ts:

El codi ha millorat perquè ara queda clar que tots aquests float estan relacionats de manera seqüencial (tenen un ordre).

També has après que pots accedir als elements d’una llista indicant la seva posició dins de la seqüència.

Elements

Una llista és una seqüència de valors que poden ser de qualsevol mena.

Els valors en una llista són anomenats elements o de vegades ítems.

Hi ha diverses maneres de crear una nova llista; la més simple, com has vist abans, és tancar els elements en claudàtors ([ i ]):

[10, 20, 30, 40]
["granota", "ovella", "estruç"]

El primer exemple és una llista de 4 int.

El segon exemple és una llista de tres str.

Els elements d’una llista no han de ser del mateix tipus.

La llista següent conté una str, un float, un int, i (mira!) una altra llista

["spam", 2.0, 5, [10, 20]]

Una llista dins d’una altra llista està imbricada (en anglès, nested).

Una llista que no conté elements és anomenada una llista buida; pots crear-ne una amb claudàtors buits, [].

Com pots veure, pots assignar els valors d’una llista a variables:

cheeses = ['Cheddar', 'Edam', 'Gouda']
numbers = [17, 123]
empty = []
print(cheeses, numbers, empty)
['Cheddar', 'Edam', 'Gouda'] [17, 123] []

Accés posicional

Pots accedir a un element d’una llista amb l’operador claudàtor indicant la seva posició:

xs = ["a","b","c","d","e","f","g","h","i","j","k","l"]
assert xs[0] == 'a'
assert xs[5] == 'f'

També pots accedir començant a contar des del final amb posicions negatives:

xs = ["a","b","c","d","e","f","g","h","i","j","k","l"]
assert xs[-1] == 'l'
assert xs[-3] == 'j'
assert xs[-0] == 'a'

Pots veure que -0 i 0 és la mateixa posició.

Que passa si intento accedir a una posició que no existeix?

xs = ["a","b","c","d","e","f","g","h","i","j","k","l"]
xs[99]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

Es produeix un IndexError

Les llistes són mutables perquè pots modificar l’element que ocupa una posició en la llista

Quan l’operador claudàtor apareix a la banda esquerra d’una assignació, aquest identifica l’element de la llista que s’assignarà.

numbers = [17, 123]
numbers[1] = 5
print(numbers)
[17, 5]

L’element a la posició 1 de numbers, que abans era 123, ara és 5.

Afegir elements

append

Amb .append(), pots afegir elements al final d’un objecte de llista existent.

El mètode .append() de Python pren un objecte com a argument i l’afegeix al final d’una llista existent, just després del seu últim element:

numbers = [1, 2, 3]
numbers.append(4)
assert numbers == [1, 2, 3, 4]

Cada vegada que crides .append() sobre una llista existent, el mètode afegeix un nou element al final, o costat dret, de la llista.

Les llistes de Python reserven espai extra per a nous elements al final de la llista. Una crida a .append() col·loca els nous elements en l’espai disponible.

A la pràctica, pots utilitzar .append() per afegir qualsevol tipus d’objecte a una llista donada

mixed = [1, 2]
mixed.append(3)
mixed.append("four")
mixed.append(5.0)
assert mixed == [1, 2, 3, 'four', 5.0]

Les llistes són seqüències que poden contenir diferents tipus de dades i objectes de Python, així que pots utilitzar .append() per afegir qualsevol objecte a una llista donada.

No obstant això, has de tenir en compte que .append() només afegeix un únic element o objecte cada vegada:

x = [1, 2, 3, 4]
y = (5, 6)
x.append(y)
assert x == [1, 2, 3, 4, (5, 6)]

extend

El mètode .extend() afegeix tots els elements d’una llista (o qualsevol iterable) al final de la llista actual.

x = [1, 2, 3, 4]
y = (5, 6, 7)
x.extend(y)
assert x == [1, 2, 3, 4, 5, 6, 7]

len

La funció d’utilitat len(llista) et mostra el número d’elements d’una llista, independentment del seu tamany.

l1 = ["HTML", "CSS", "JavaScript"]
assert len(l1) == 3

+

L’operador + concatena dues llistes creant una nova llista amb els seus elements.:

a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
assert c == [1, 2, 3, 4, 5, 6]

Activitats

Activitat

A continuació tens una llista de noms

names = ["Manel", "Roser", "Omar", "Laura"]
name = "David"

Afegeix name al final de la llista:

Afegeix aquesta llista ["Jordi", "Claudia", "Rosa"] al final del names:

Mostra el número d’elements de la nova llista.

Crea una llista nova amb names i ["Robert", "Joana"]:

for

Una de les operacions més habituals és recórrer una llista del principi al final per obtenir un resultat.

Fes un print de tots els elements de la llista:

for i in ts:
print(i)

Com ja vam explicar a Python - Computació, un dels usos més habituals d’una variable és anar acumulant el resultat d’operacions que anem fent.

Si vols sumar el contingut de la llista, pots anar acumulant els valors parcials en en una variable:

sum = 0
for t in ts:
sum += t
medium = sum / 5
print(f"{medium:.2f")

Activitats

Activitat

Donada una llista de temperatures, digues quina és la més alta:

ts = [25.6, 26, 27, 24.3, 28, 24.5, 26.7]
Activitat

Donada la llista de temperatures, calcula la suma de temperatures i la mitjana aritmètica:

ts = [25.6, 26, 27, 24.3, 28, 24.5, 26.7]

in

L’operador in et permet saber si un element està en una llista:

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']
>>> 'Edam' in cheeses
True
>>> 'Brie' in cheeses
False
Activitat

Si tens una llista de noms, amb l’operador in pots saber si la "laura" està dins la llista:

ns = ["joan", "laura", "jordi", "esther", "david", "miquel"]
assert "laura" in ns

Escriu un codi que enlloc d’utilitzar in (la solució simple que has de fer servir en la majoria dels casos), utilizi un for per buscar la "laura":

Slice

L’operador “slice” et permet crear una llista amb només alguns elements d’una altra llista.

Per exemple, imagina que tens la llista xs:

xs = [3,5,5,6,3,4,3,7,8,9,7,6,6,4]

Si només vols els tres primers elements de la llista …

Doncs fas un “slice” de xs amb xs[:3]:

xs = [3,5,5,6,3,4,3,7,8,9,7,6,6,4]
ys = xs[:3]
assert ys == [3,5,5]

Si vols imprimir els tres primers elements de la llista:

  1. Fas un “slice”
  2. Fas un for del “slice”
xs = [3,5,5,6,3,4,3,7,8,9,7,6,6,4]
for x in xs[:3]:
print(x)

Sintaxi

La sintaxi bàsica per crear un slice a Python és la següent xs[start:end:step], on:

  • start: Índex on comença el slice, per defecte 0
  • end: Índex on acaba l’slice, per defecte len(xs)
  • step: Mida del pas entre elements de l’slice, per defecte 1.

Si utilitzes tots els valors per defecte, el resultat és una llista amb tots els elements de la llista original.

xs = [6, 7, -3, 34]
ys = xs[::]
assert ys == xs

Has creat una llista ys idèntica a xs.

Edició de llistes amb slices.

Com que les llistes són mutables, de vegades és útil fer-ne una còpia abans de fer operacions que la modifiquen.

Un operador slice al costat esquerre d’una assignació et permet actualitzar múltiples elements; com substituïr elements de llistes.

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> t[1:3] = ['x', 'y']
>>> print(t)
['a', 'x', 'y', 'd', 'e', 'f']

Activitats

Activitat

Obre un terminal interactiu i fes provant diferents “slices” amb una llista de números.

>>> xs = ["a","b","c","d","e","f","g","h","i","j","k","l"]
>>> xs[2:5]
['c', 'd', 'e']
>>> xs[-3:-1]
['j', 'k']
Activitat

Fes un “slice” amb els tres últims elements de la llista:

xs = [1,2,3,4,5,6,7]
Activitat

Recorre aquesta llista a la inversa i saltant de 3 en 3.

xs = [3,5,5,6,3,4,3,7,8,9,7,6,6,4]

sort

Ordenar llistes amb Python és molt senzill. Podem utilitzar una funció que ens permet generar la llista ordenada.

list.sort(reverse=True|False, key=myFunc))

La funció sort té 2 paràmetres opcionals:

  • reverse si és igual a True mostra la llista en ordre invers. Per defecte el valor es false.
  • key si volem ordenar amb altres criteris diferents de l’alfabètic o els nombres ordinals ho podeu fer des d’aquí. Per defecte està buit. Ho veurem més endavant.

Anem a veure dos exemples:

>>> languages = ['Rust', 'Python', 'C', 'PHP', 'Java']
>>> languages.sort()
>>> print(languages)
['C', 'Java', 'PHP', 'Python', 'Rust']
>>> pluges = [0.2, 8.6, 34.4, 16.5, 81.3, 2.8]
>>> pluges.sort(reverse=True)
>>> print(pluges)
[81.3, 34.4, 16.5, 8.6, 2.8, 0.2]
# Retornarà None, ja que la funció sort no retorna cap valor, només ordena.
#print(pluges.sort(reverse=True))
Activitat

Tenim dues llistes amb el volum en mL d’unes ampolles. Fes que la segona llista estigui després de la primera. Després, crea una nova llista amb els números ordenats de major a menor.

water_level = [730, 709, 682, 712, 733, 751, 740]
new_water_level = [772, 770, 745]

List Comprehension

Una list comprehension et permet efectuar operacions amb llistes amb una sintaxi més curta que amb un for.

El resultat sempre és una llista.

Filtrar

Per exemple, si tens aquesta llista:

xs = [6, 7, -3, 34, -8, -10, 3]

Amb un for pots crear una llista nova només amb els nombres positius:

xs = [6, 7, -3, 34, -8, -10, 3]
ys = []
for x in xs:
if x >= 0:
ys.append(x)
print(ys)

Amb una “list-comprehension” la sintaxi és més curta:

ys = [x for x in xs if x >= 0]
assert xs == [6, 7, 34, 3]

De moment només fixa’t en la part que ve després del if.

Aquest if avalua la condició que ve a continuació, i si aquesta és True, l’element x s’afegeix a la llista resultant.

Activitat

Crea una llista amb només aquells números que son divisibles per 2.

Activitat

A continuació tens una llista de fruites.:

fruits = ["apple", "banana", "cherry", "kiwi", "mango"]

Crea una llista nova que contingui només les fruites amb la lletra “a” al nom:

Transformar

A continuació tens una llista de números:

xs = [10, 20, 30, 40]

I l’algoritme per crear una llista amb els valors duplicats de la llista original:

ys = []
for x in xs:
ys.append(x * 2)
assert ys == [20, 40, 60, 80]

Amb una list comprehension és més senzill:

xs = [10, 20, 30, 40]
ys = [x + 2 for x in xs]
assert ys == [20, 40, 60, 80]

Abans del for escrius l’operació que vols fer amb cada element de la llista original.

Esquema resum de les list Comprehension:

Activitat

Tens una llista de preus:

prizes = [1.60, 2.25, 3.50, 4.80, 6.75]

Crea una llista nova amb els preus incrementats un 20 %

filtrar i transformar

Una operació habitual és filtrar i transformar els elements d’una llista.

Això té més sentit quan treballes amb Python - Dades, com quan vols filtrar una llista de persones per obtenir el seu telèfon per exemple.

Però fins llavors, un exemple senzill:

xs = [5, 10, 15, 20, 25, 30]
ys = [x + 2 for x in xs if x % 2 == 0]
assert ys == [12, 22, 32]

Si encara és massa complicat per tu fer les dos coses a la vegada en una sola expressió, ho pots fer pas a pas:

xs = [5, 10, 15, 20, 25, 30]
ys = [x for x in xs if x % 2 == 0]
assert ys == [10, 20, 30]
ys = [x + 2 for x in ys]
assert ys == [12, 22, 32]

range

La funció range et permet generar automàticament seqüències de números.

Per exemple, si vols mostrar els números de l’1 al 5 sense crear un bucle i posar-los en una llista.

ns = list(range(1,5))
print(ns)

És una forma més eficient i legible que usar un bucle i posar els números un a un, com ho faríem:

i: int = 0
while i < 11:
numbers[i]=i
i+=1
print(numbers)

La conversió del range a list és molt menys costosa que el bucle.

Com els slices, la funció range té 3 paràmetres:

  • start: Opcional. Número d’inici del rang. Per defecte és el 0.
  • stop: Obligatori. Valor final del rang.
  • step: Opcional. Per defecte 1. És útil si volem crear un rang seguint un patró (per exemple, de 3 en 3).

Exercicis (range i list comprehension)

1. A partir d’una llista, que va del 1 al 10, crea una nova llista amb els valors al quadrat de la primera.

2. Tenim una llista de productes. Has de crear una nova llista que apliqui el 21% d’IVA i només hi hagi els que tenen un preu inferior a 100.0

preus = [75.50, 88.00, 100.50, 96.75, 69.90]

Resultat esperat:

['91.36', '84.58']

Pendent