Lista - modelul conceptual liniar
Definiție: Lista este un model conceptual liniar de organizare a datelor, în care elementele sunt aranjate una după alta, în ordine, fiecare având o poziție bine stabilită.
Caracteristici: ordine fixă, acces direct după index (poziție), primul element are indexul 0, ultimul element al unei liste cu n elemente are indexul n - 1, fiecare element are un precedent și un succesor.
Acces direct = ajungem imediat la element după poziția lui (v[4]); acces secvențial = parcurgem elementele unul câte unul, de la primul.
Stiva și coada
Stiva respectă principiul LIFO (Last In, First Out): ultimul element introdus este primul scos. Se simulează cu append() și pop(). Analogie: farfuriile stivuite, anularea ultimei acțiuni, istoricul browserului.
Coada respectă principiul FIFO (First In, First Out): primul element introdus este primul scos. Se simulează cu append() și pop(0). Analogie: rândul la ghișeu, imprimanta, mesajele primite în ordine.
Lista permite acces direct la orice element, pe când stiva și coada impun o ordine de procesare a datelor.
| Criteriu | Stiva (LIFO) | Coada (FIFO) |
|---|---|---|
| Principiu | Last In, First Out - ultimul introdus este primul scos | First In, First Out - primul introdus este primul scos |
| Adăugare | stiva.append(x) - se pune în vârf |
coada.append(x) - se pune la coadă |
| Scoatere | stiva.pop() - din vârf (ultimul introdus) |
coada.pop(0) - din față (primul introdus) |
| Analogie | Farfuriile stivuite, Ctrl+Z, istoricul browserului | Rândul la ghișeu, imprimanta, mesajele primite în ordine |
| Când o folosim? | Când trebuie inversată ordinea ultimei acțiuni | Când trebuie respectată ordinea sosirii |
Reține: diferența dintre cele două structuri este doar de unde se scoate: pop() din vârf pentru stivă, pop(0) din față pentru coadă. Adăugarea se face identic, cu append().
Clasa list - caracteristici și operatori
În Python, lista este o colecție mutabilă, ordonată de elemente: putem modifica elementele după crearea listei, păstrăm ordinea de introducere și accesăm fiecare element după index, începând de la 0.
| Operator | Rol | Exemplu |
|---|---|---|
[] |
Acces la elementul de pe o poziție | v[2] dă al treilea element; v[-1] ultimul |
in / not in |
Verifică apartenența unei valori | 5 in v dă True sau False |
+ |
Concatenarea a două liste (listă nouă) | v + w unește listele în ordine |
* |
Multiplicarea (repetarea) listei | v * 2, [0] * 11 |
==, != |
Compară listele element cu element | v == [1, 2, 3] |
<, > |
Comparare lexicografică | [1, 2] < [1, 3] este True |
Metodele clasei list - tabel recapitulativ
Metodele care modifică lista (append, insert, extend, pop, remove, clear, sort, reverse) returnează None. Metodele care returnează informații: index(), count(); copy() returnează o listă nouă.
| Metodă | Efect asupra listei | Exemplu |
|---|---|---|
append(x) |
Adaugă x la finalul listei | v.append(7) |
insert(i, x) |
Introduce x pe poziția i | v.insert(1, 7) |
extend(w) |
Adaugă elementele din w la final | v.extend([7, 8]) |
pop(i) |
Scoate elementul de pe poziția i (fără argument, ultimul) și îl returnează | x = v.pop() |
remove(x) |
Șterge prima apariție a valorii x | v.remove(7) |
clear() |
Golește complet lista | v.clear() |
index(x) |
Returnează poziția primei apariții a lui x | p = v.index(7) |
count(x) |
Returnează numărul de apariții ale lui x | c = v.count(7) |
sort() |
Ordonează lista crescător (reverse=True pentru descrescător) | v.sort() |
reverse() |
Inversează ordinea elementelor | v.reverse() |
copy() |
Creează o copie independentă a listei | w = v.copy() |
Copiere versus atribuire
Atribuirea w = v nu creează o listă nouă: ambele variabile indică aceeași listă din memorie, deci orice modificare prin w se vede și prin v. Pentru o listă independentă, care poate fi modificată fără a afecta originalul, folosim w = v.copy().
| Criteriu | Atribuire w = v |
Copiere w = v.copy() |
|---|---|---|
| Ce se întâmplă? | Două nume pentru aceeași listă | Se creează o listă nouă, cu aceleași valori |
w.append(9) îl schimbă și pe v? |
Da, ambele cresc | Nu, doar w se modifică |
| Când o folosim? | Doar când vrem același obiect | Când păstrăm originalul (ex.: sortăm o copie) |
v = [3, 1, 2] w = v # aceeași listă w.sort() # v se modifică și el! print(v) # [1, 2, 3] w = v.copy() # listă independentă w.append(9) print(v) # [1, 2, 3] - rămâne neschimbat print(w) # [1, 2, 3, 9]
Reține: folosește copy() înainte de sort() când trebuie să păstrezi lista originală, exact cum cere proiectul modulului la nivelul de nota 9-10.
Parcurgerea unei liste
Parcurgerea fără memorare prelucrează fiecare valoare pe măsură ce o citim, fără a o stoca; folosim sume, contoare, minim și maxim. Potrivită pentru: sumă, numărare, min, max.
Parcurgerea cu memorare stochează toate valorile într-o listă și o parcurge de câte ori este nevoie; obligatorie când un calcul global (media, maximul) decide prelucrarea elementelor. Potrivită pentru: medie, valori peste medie, ordonare, analiza datelor.
Funcții utile: len(v), sum(v), min(v), max(v); media = sum(v) / len(v).
| Criteriu | Parcurgere fără memorare | Parcurgere cu memorare |
|---|---|---|
| Ce reținem? | Doar rezultatele: sumă, contor, minim, maxim | Toate valorile, stocate într-o listă |
| Câte treceri prin date? | Una singură, valorile se prelucrează pe loc | Lista rămâne și poate fi parcursă de mai multe ori |
| Potrivită pentru | Sumă, numărare, minim, maxim | Medie, valori peste medie, ordonare, analiza datelor |
| Întrebare tipică | „Afișează suma și maximul" | „Câte valori sunt peste medie?" |
n = int(input())
s = 0
cnt = 0
for i in range(n):
x = int(input()) # valoarea se prelucrează, apoi se pierde
s += x
if x % 2 == 0:
cnt += 1
print(s, cnt)
n = int(input())
v = list(map(int, input().split())) # stocăm întreaga listă
media = sum(v) / n
print("Media:", round(media, 2))
for x in v:
if x > media:
print(x, end=" ")
Reține: dacă un calcul global (media, maximul) este necesar pentru a decide despre fiecare element, memorarea este obligatorie: nu poți spune „câte note sunt peste medie" fără a cunoaște media de la finalul citirii.
Lista de frecvențe
Definiție: O listă de frecvențe este o listă în care pe poziția i se află numărul de apariții ale valorii i într-o colecție de date.
Construire în doi pași: inițializare fr = [0] * 11 (toate pozițiile cu 0), apoi incrementare fr[x] += 1 la fiecare apariție.
Interpretare: fr[x] = de câte ori apare x; poziția maximului din fr = valoarea cea mai frecventă; afișarea poziției i de fr[i] ori = ordonarea valorilor.
Dimensiune: lista trebuie să acopere intervalul valorilor; pentru note de la 1 la 10 folosim [0] * 11 (indici 0-10).
Ce trebuie să știi pentru test
Verifică-l pe fiecare rând: dacă poți explica și scrie singur fiecare punct de mai jos, ești pregătit pentru evaluare.
- Să definesc lista ca model liniar și să explic accesul direct versus secvențial, indexarea de la 0 și
v[n - 1]/v[-1]. - Să explic stiva (LIFO) și coada (FIFO) cu analogii și să le simulez cu
append(),pop()șipop(0). - Să folosesc operatorii listei:
[],in,not in,+,*, comparațiile. - Să aleg și să aplic metodele:
append,insert,extend,pop,remove,clear,index,count,sort,reverse,copy. - Să deosebesc parcurgerea cu memorare de cea fără memorare și să știu când fiecare este obligatorie (media!).
- Să construiesc și să interpretez o listă de frecvențe și să aflu valoarea cea mai frecventă.
- Să deosebesc copierea (
copy()) de atribuire (=). - Să scriu o problemă completă: citire, prelucrare, afișare, respectând exact formatul cerut de enunț.
Algoritmul 1: Citire și afișare listă
n = int(input())
v = list(map(int, input().split()))
print(v)
print("Primul:", v[0])
print("Ultimul:", v[n - 1])
Algoritmul 2: Media și valorile peste medie
n = int(input())
v = list(map(int, input().split()))
media = sum(v) / n
print("Media:", round(media, 2))
cnt = 0
for x in v:
if x > media:
print(x, end=" ")
cnt += 1
print()
print("Peste medie:", cnt)
Algoritmul 3: Lista de frecvențe
n = int(input())
v = list(map(int, input().split()))
fr = [0] * 11
for x in v:
fr[x] += 1
for i in range(11):
print(i, ":", fr[i])
Algoritmul 4: Simularea stivei și a cozii
stiva = [10, 20, 30]
while stiva:
print("Scos din stiva:", stiva.pop())
coada = ["Andrei", "Maria", "Ion"]
while coada:
print("Servit din coada:", coada.pop(0))
Algoritmul 5: Gestiunea stocurilor (operatori + metode)
d1 = [12, 8, 15]
d2 = [5, 14, 9]
stoc_total = d1 + d2
print(stoc_total)
print(len(stoc_total))
comenzi = ["caiet", "pix", "caiet"]
print(comenzi.count("caiet"))
print(comenzi.index("pix") + 1)
Provocarea 1: Cea mai frecventă notă
Enunț: Se citesc n note (numere întregi de la 1 la 10). Afișează media notelor și cea mai frecventă notă, împreună cu numărul de apariții. Probleme de acest tip combină parcurgerea cu memorare cu lista de frecvențe.
n = int(input())
note = list(map(int, input().split()))
media = sum(note) / n
print("Media:", round(media, 2))
fr = [0] * 11
for x in note:
fr[x] += 1
frecventa_maxima = max(fr)
nota = fr.index(frecventa_maxima)
print("Nota", nota, "apare de", frecventa_maxima, "ori")
Provocarea 2: Suma și numărarea fără listă
Enunț: Se citesc n numere întregi, unul câte unul. Afișează suma numerelor și câte dintre ele sunt pare, fără a stoca valorile într-o listă (parcurgere fără memorare).
n = int(input())
s = 0
cnt = 0
for i in range(n):
x = int(input())
s += x
if x % 2 == 0:
cnt += 1
print("Suma:", s)
print("Numere pare:", cnt)
Provocarea 3: Stocuri și comenzi
Enunț: Un magazin are lista produselor din două depozite. Unește stocurile cu +, apoi afișează de câte ori apare produsul „pix" în comenzi și poziția primei comenzi de „caiet" (numărătoare de la 1).
depozit1 = ["caiet", "pix", "caiet"]
depozit2 = ["pix", "radiera"]
stoc = depozit1 + depozit2
print("Stoc complet:", stoc)
print("Pixuri comandate:", stoc.count("pix"))
print("Prima comanda de caiet:", stoc.index("caiet") + 1)
Verifică: count("pix") returnează 2, iar index("caiet") returnează poziția 0, deci adunăm 1 pentru a obține „prima comandă", adică 1. Încearcă să rulezi și să modifici fiecare rezolvare înainte de test.
Reguli esențiale și greșeli frecvente
Reguli de aur
- Indexarea începe de la
0: ultimul element al unei liste cu n elemente estev[n - 1]sauv[-1]. - Verifică cu
inînainte deindex()șiremove(), altfel obțiiValueError. - Metodele care modifică lista returnează
None: nu scrie niciodatăv = v.sort(). - Pentru o copie independentă folosește
v.copy(), nu atribuireaw = v. - Memorează lista ori de câte ori un calcul global (media) este necesar pentru decizii ulterioare.
- Lista de frecvențe se inițializează cu
0și se incrementează cu+= 1, acoperind tot intervalul valorilor. - La egalități de frecvență, citește enunțul: folosește
>pentru a păstra prima (cea mai mică) valoare.
Greșeli frecvente la test
v[n]în loc dev[n - 1]pentru ultimul element, producândIndexError.- Confuzia stivei (LIFO,
pop()) cu coada (FIFO,pop(0)). fr[x] = 1în loc defr[x] += 1la lista de frecvențe.- Compararea valorilor cu media rotunjită în loc de media exactă.
- Uitarea
+1laindex()când numărătoarea începe de la 1 (luni, zile, elevi). - Modificarea listei (
remove,pop) în timpul parcurgerii cufor. - Uitarea
int()saufloat()la conversia datelor citite. - Rezolvarea cu parcurgere fără memorare atunci când enunțul cere media: datele trebuie stocate în listă.
- Afișarea întregii liste cu
print(v)când enunțul cere elemente separate prin spații (print(*v)). - Scrierea
w = vîn loc dew = v.copy()când lista originală trebuie păstrată.
Sfaturi pentru test și proiect
- Scrie întâi pseudocodul complet, apoi codul Python, pas cu pas.
- Testează întotdeauna programul pe exemplul din enunț, verificând manual rezultatul.
- Pentru valori reale citește cu
map(float, ...)și rotunjește la afișare curound(). - La proiect, modularizează: o funcție pentru citire, una pentru prelucrare, una pentru afișare.
- Revizuiește codul final și explică fiecare linie, ca la susținerea orală.