Obținerea unui singur element
Această lecție arată cum să obții un singur element dintr-o listă: după poziția lui, după o condiție sau la întâmplare. Arată și cum să verifici dacă un element există.
Python are None, o valoare specială care înseamnă „nicio valoare”. Când o căutare poate eșua, o funcție Python poate returna elementul sau None, iar codul care o apelează testează rezultatul cu is not None.
Citirea unei poziții care nu există, cum ar fi words[5] într-o listă cu 5 elemente, oprește programul cu o eroare IndexError (o eroare la rulare). De aceea, fie verificăm mai întâi len(), fie folosim o funcție ajutătoare care face asta.
Alte limbaje au multe funcții gata făcute pentru asta. Python se limitează la câteva unelte: parantezele pătrate, funcția încorporată next() cu o valoare implicită și o mică funcție ajutătoare pe care o scrii o singură dată.
Obținerea după poziție
Fiecare element dintr-o listă are o poziție numită index. Primul index este 0, deci ultimul este len(words)-1.
Pentru a citi un element după poziție, scrie indexul între paranteze pătrate: words[3]. Python numără și de la sfârșit: un index negativ, cum ar fi words[-1], citește ultimul element fără niciun calcul cu lungimea.
Python nu are element_at_or_none() sau element_at_or_else(). O mică funcție ajutătoare verifică indexul față de len() și returnează fie elementul, fie None, fie rezultatul unei funcții de rezervă. Astfel, un index în afara intervalului nu poate genera o eroare IndexError.
Elementul de la o poziție
words[3] citește elementul de la indexul 3. Deoarece numărarea începe de la 0, acesta este al patrulea cuvânt.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
# Pozițiile încep de la 0, deci indexul 3 este al patrulea element.
print(words[3])
Primul și ultimul element
Primul element este words[0]. Ultimul este words[-1]: un index negativ numără de la sfârșit, deci -1 este ultimul element, iar -2 cel dinaintea lui.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
# Primul element este la indexul 0; un index negativ numără de la sfârșit.
print(words[0])
print(words[-1])
Elementul de la o poziție sau None
element_at verifică indexul față de len(). Indexul 1 este în interval, deci returnează cuvântul two. Indexul 5 este în afara intervalului, deci returnează None în loc să genereze o eroare IndexError.
Ieșire: program Python complet
def element_at(items, i):
# None în loc de IndexError când indexul este în afara intervalului.
if i < 0 or i >= len(items):
return None
return items[i]
words = ["one", "two", "three", "four", "five"]
print(element_at(words, 1))
# Indexul 5 nu există: niciun IndexError, doar None.
print(element_at(words, 5))
Elementul de la o poziție sau o valoare de rezervă
element_at_or_else primește o funcție de rezervă. Funcția primește indexul, așa că poate construi un mesaj precum „Valoarea pentru indexul 5 nu este definită”.
Ieșire: program Python complet
def element_at_or_else(items, i, fallback):
# În afara intervalului: returnează în schimb rezultatul lui fallback(i).
if i < 0 or i >= len(items):
return fallback(i)
return items[i]
words = ["one", "two", "three", "four", "five"]
print(element_at_or_else(words, 5,
lambda i: f"Valoarea pentru indexul {i} nu este definită"))
Obținerea după condiție
Deseori nu cunoști poziția. În schimb, cunoști o condiție: primul cuvânt mai lung de 3 litere, ultimul cuvânt care începe cu „f”. Condiția stă într-o expresie generator, cum ar fi w for w in words if len(w) > 3, care produce doar cuvintele care se potrivesc.
Pentru prima potrivire, transmite generatorul funcției încorporate next(). Aceasta ia prima valoare pe care o produce generatorul și nu se mai uită la restul. Când nimic nu se potrivește, next() generează o eroare StopIteration — doar dacă nu îi dai un al doilea argument, o valoare implicită, care este returnată în schimb.
Nu există o funcție pentru ultima potrivire. reversed() parcurge lista invers, deci next() peste un generator inversat găsește ultima potrivire: prima găsită în timpul parcurgerii inverse este ultima din listă.
Cu None ca valoare implicită, „nimic nu s-a potrivit” este doar un rezultat care is None.
Prima potrivire
next() ia primul cuvânt pe care generatorul îl produce cu len(w) > 3. Acel cuvânt este three.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
# next() ia prima valoare pe care o produce generatorul.
first = next(w for w in words if len(w) > 3)
print(first)
Ultima potrivire
Generatorul parcurge reversed(words), deci pornește de la sfârșit. Primul cuvânt întâlnit care începe cu "f" este five, așa că next() îl returnează, iar celelalte cuvinte nu mai sunt verificate.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
# reversed() parcurge de la sfârșit, deci prima potrivire este ultima potrivire.
last = next(w for w in reversed(words) if w.startswith("f"))
print(last)
Prima potrivire sau None
Niciun cuvânt nu are mai mult de 6 litere, deci next() returnează valoarea implicită None, iar programul afișează „nu a fost găsit”. În lista de numere, primul număr par este 2.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
numbers = [1, 2, 3, 4]
# Al doilea argument al lui next() este valoarea implicită pentru „nimic nu s-a potrivit”.
found = next((w for w in words if len(w) > 6), None)
if found is not None:
print(found)
else:
print("nu a fost găsit")
even = next((n for n in numbers if n % 2 == 0), None)
if even is not None:
print(even)
Ultima potrivire sau None
reversed(numbers) parcurge numerele invers. Ultimul număr par este 4 și este găsit imediat.
Ieșire: program Python complet
numbers = [1, 2, 3, 4]
# Parcurgem invers: primul număr par de la sfârșit este ultimul.
last_even = next((n for n in reversed(numbers) if n % 2 == 0), None)
if last_even is not None:
print(last_even)
Obținerea cu un selector
Uneori vrei mai întâi să transformi fiecare element și apoi să iei primul rezultat potrivit.
O funcție selector face transformarea și returnează None pentru rezultatele care nu se potrivesc. map() aplică selectorul fiecărui element, iar next() cu un test is not None ia primul rezultat bun. Lista de aici conține în același timp un număr, un șir și o valoare bool — o listă Python poate amesteca tipuri. str() transformă orice valoare în text.
Prima valoare transformată care se potrivește
Fiecare valoare este transformată în text cu str(). 0 devine "0", care este prea scurt, deci selectorul returnează None. "true" are 4 caractere, deci este primul rezultat care nu este None, iar programul afișează true.
Ieșire: program Python complet
values = [0, "true", False]
def long_text(v):
# Transformă valoarea în text; textele scurte nu se potrivesc și devin None.
s = str(v)
return s if len(s) >= 4 else None
# Primul rezultat al selectorului care nu este None.
found = next((s for s in map(long_text, values) if s is not None), None)
print(found)
Element aleatoriu
Pentru a alege un element aleatoriu, alege un index aleatoriu. Modulul random oferă numere aleatorii; rng.randrange(n) returnează un număr de la 0 până la n-1, adică exact intervalul indexurilor valide.
Python are și rng.choice(), care alege direct un element. Acest exemplu alege mai întâi un index, ca să-l poți vedea; choice() face același lucru dintr-un singur apel.
Un generator creat cu random.Random(42) pornește de la un seed fix. Cu același seed, programul alege de fiecare dată același element, ceea ce face ieșirea previzibilă — exemplul își inițializează propriul generator cu seed exact din acest motiv. Folosește random.Random() fără seed când vrei un rezultat diferit la fiecare rulare.
Alegerea unui element aleatoriu
Cu seed-ul 42, generatorul alege indexul 0, deci programul afișează 1. Schimbă seed-ul și poate apărea un alt număr.
Ieșire: program Python complet
import sys
# Acest fișier se numește random.py, iar Python caută modulele mai întâi lângă
# script. Eliminăm acea cale, ca „import random” să găsească modulul real.
del sys.path[0]
import random
numbers = [1, 2, 3, 4]
# Un seed fix face ca alegerea „aleatorie” să fie aceeași la fiecare rulare.
rng = random.Random(42)
i = rng.randrange(len(numbers))
print(numbers[i])
Verificarea existenței unui element
Pentru a verifica dacă o valoare este într-o listă, folosește operatorul in. Acesta returnează True sau False.
Python nu are contains_all(). Funcția încorporată all() face asta într-o singură linie: all(v in items for v in wanted) este True doar când fiecare valoare căutată este găsită. Se oprește imediat ce lipsește o valoare.
Python nu are nici is_empty(). Compară lungimea: len(s) == 0 înseamnă gol, len(s) > 0 înseamnă că nu este gol. Varianta specifică Python este și mai scurtă: o listă goală contează ca False într-o condiție, așa că majoritatea codului Python scrie if not words: pentru „gol” și if words: pentru „nu este gol”. Această pagină afișează verificările de lungime, pentru că ele spun exact ce se măsoară.
Conține o valoare
"four" este în listă, deci prima verificare este True. "zero" nu este, deci a doua verificare este False.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
print("four" in words)
print("zero" in words)
Conține toate valorile
Atât "four", cât și "one" sunt în listă, deci contains_all returnează True. "zero" lipsește, deci al doilea apel returnează False.
Ieșire: program Python complet
def contains_all(items, wanted):
# True doar când fiecare valoare căutată se găsește în items.
return all(v in items for v in wanted)
words = ["one", "two", "three", "four", "five"]
print(contains_all(words, ["four", "one"]))
print(contains_all(words, ["one", "zero"]))
Gol sau nu
empty are lungimea 0, deci len(empty) == 0 este True. words are 5 elemente, deci și len(words) > 0 este True.
Ieșire: program Python complet
words = ["one", "two", "three", "four", "five"]
empty = []
# O listă este goală când lungimea ei este 0.
print(len(empty) == 0)
print(len(words) > 0)