#wit.py – Structuri de date Partea 1
1Rezolvarea temei
Rezolvarea a fost scrisă de Luca George şi este corectă.
Exercitiul 1:
nume = raw_input("Nume : ") print "Salutare, " + nume + "."
Exercitiul 2:
a = raw_input('Introduceti numele ultimei carti citite: ') print ''Ultima data am citit \'' + a + '\''
Felicitări pentru rezolvare!
Structuri de date
Liste
Listele sunt prima structură de date despre care vom vorbi astăzi. O listă este defapt un tablou unidimensional ce poate conţine orice alt tip de date, inclusiv: variabile de tip long (marcate cu un L la sfârşit), stringuri (fără a le separa în caractere) şi chiar şi alte liste, aşa cum puteţi vedea în acest exemplu.
ion = ['Popescu Ion', 42] george = ['Frunzescu George', 51] database = [ion, george]
După cum aţi putut vedea, listele sunt marcate de paranteze pătrate, obiectele listei sunt delimitate de virgulă, iar stringurile sunt scrise între ghilimele pentru a nu fi confundate cu o structură de date cu acel nume.
Listele şi stringurile suportă indexarea, astfel, dacă am avea: string = ‘Salut’, apelând string[0] se va afişa ‘S’. Acest lucru de poate folosi cu orice număr până la 4 (stringul are 5 caractere, dar primul este 0). Dacă ne-ar interesa ultima literă am folosi string[-1] (idem pentru -2, -3…). Indexarea se mai poate face în două cazuri, stringuri introduse direct, fără a se folosi o structură de date:
>>> 'Salut'[1] 'a'
şi în timpul citirii:
>>> nume = raw_input('Introduceti numele: ')[0] Introduceti numele: Bogdan >>> nume 'B'
Notă! După caracterele >>> vă puteţi da seama că acest cod a fost preluat din interpretor. Rândurile precedate de aceste caractere sunt introduse de mine în interpretor, iar celelalte sunt afişate de acesta.
Un exemplu pentru folosirea listelor este programul următor care citeşte o dată şi o va afişa în formatul: 24 mai 2012
# Afisarea datei, primind anul, luna, si ziua ca numere lunile = [ 'ianuarie', 'februarie', 'martie', 'aprilie', 'mai', 'iunie', 'iulie', 'august', 'septembrie', 'octombrie', 'noiembrie', 'decembrie' ] an = raw_input('Anul: ') luna = raw_input('Luna (1-12): ') ziua = raw_input('Ziua (1-31): ') luna_numeric = int(luna) ziua_numeric = int(ziua) # Nu uita sa scazi 1 din luna si ziua pentru a obtine indexul corect nume_luna = lunile[luna_numeric-1] print ziua + ' ' + nume_luna + ' ' + an raw_input()
Slicing
Această tehnică reprezintă folosirea indexării într-un interval. Pentru a înţelege cum funcţionează, aveţi exemplul următor:
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> numbers[3:6] [4, 5, 6] >>> numbers[0:1] [1]
Se poate folosi şi aici şmecheria cu numerele negative:
>>>numbers[-3:-1] [8, 9]
Dar dacă vrem să folosim ultimele 2 caractere din această listă, ce facem?
>>> numbers[-2:0] []
Nu e rezultatul aşteptat. Totuşi, de ce este returnată o listă goală? Tot timpul când elementul reprezentat de termenul din stânga apare după cel din dreapta (adică, penultimul element faţă de primul) este returnată o listă goală. Soluţia problemei este
>>> numbers[-2:] [9, 10]
Acel spaţiu gol de după (sau de dinainte, după caz) de : reprezintă capătul listei. Se poate folosi şi astfel:
>>> numbers[:3] [1, 2, 3]
Defapt, pentru a afişa întreaga listă se poate folosi şi:
>>> numbers[:] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Se poate specifica şi un al treilea număr după alte două puncte, care reprezintă „saltul” făcut în timpul parcurgerii
>>> numbers[0:10:2] [1, 3, 5, 7, 9]
Se poate specifica chiar şi un număr negativ
>>> numbers[10:0:-2] [10, 8, 6, 4, 2]
Adunare şi multiplicare
Pe scurt, adunarea funcţionează astfel:
>>> [1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] >>> 'Hello, ' + 'world!' 'Hello, world!' >>> [1, 2, 3] + 'world!' Traceback (innermost last): File "<pyshell#2>", line 1, in ? [1, 2, 3] + 'world!' TypeError: can only concatenate list (not "string") to list
iar multiplicarea va afişa un string de un anumit număr de ori:
>>> 'python' * 5 'pythonpythonpythonpythonpython' >>> [42] * 10 [42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
Tuples
Ele sunt marcate de paranteze rotunde, iar diferenţa semnificativă dintre liste şi tuples este că cele din urmă NU pot fi modificate. Câteva exemple:
>>> 1, 2, 3 (1, 2, 3)
>>> (1, 2, 3) (1, 2, 3)
>>> 42 42 >>> 42, (42,) >>> (42,) (42,)
Aşa cum aţi observat, doar scriind mai multe numere, separate de virgulă, vom obţine un tuple, iar pentru a crea un tuple cu un singur element, acesta va trebui precedat de virgulă.
Notă de final
Articolul a ajuns destul de lung şi am considerat că voi prezenta restul despre liste şi tuples în articolul următor.
*Am folosit exemple de cod din cartea Beginning Python: From Novice to Professional de Magnus Lie Hetland, ISBN: 159059519X *
Temă
De această dată nu voi da o temă, aceasta va fi publicată doar după terminarea întregii serii Structuri de date.
Bun articol, mai ales partea de slicing. Ca o completare, daca nu stiti ce sa alegeti dintre lista sau tuple, trebuie sa aveti in vedere ca un tuple e mult mai rapid decat o lista si se comporta mai bine pe iteratii, stocari date, impachetari, respectiv despachetari. Totusi aceasta „optimizare” are ca dezavataj lipsa unor membri importanti (read only) ca find (disparea nevoia incadrarii instructiunii intr-un bloc try) si (dupa cum a specificat si autorul) alte metode folositoare de manipulare a acestor obiecte.
Legat de slicing un smen misto e sa folositi in loc de reversed sau .reverse, cevaIterabil[::-1].
Desi la nivel de sintaxa python nu are pointeri, in practica sa nu uitati ca atunci cand pasati ca argumente unor functii liste acestea vor fi pasate ca referinte si daca modificati undeva lista se modifica un singur loc din memorie ceea ce rezulta in „modificarea” listei si in celelalte locuri de vizibilitate a obiectului asa ca nu va sfiiti sa folositi [:] pentru duplicate (unii ar prefera copy din modulul copy).
In python3 exista doar input echivalent cu raw_input din 2.x, iar in python2 raw_input e un fel de str(input) exista si input dar preia ce sa da ca cod nu ca sir, s-a renuntat la acel comportament al lui input din 2.x pentru ca expunea scriptul la vulnerabilitati cum ar fi executie de cod malitios.