Viaggio tra le Collection di Python

Breve introduzione alle collezioni Python, strumento molto utile ma troppo spesso ignorato

Non mi è capitato spesso di vederle usate e molti sviluppatori le ignorano, ma le collezioni sono uno strumento utilissimo per risolvere rapidamente particolari tipi di problemi.

Python le supporta dalla versione 2.4, spesso tramite attività di backport da Python-3.

Il modulo in questione è il modulo della lib standard collections ed in particolare analizzeremo quello della versione più recente della serie 2.x, il 2.7.3.

Le tipologe di collezioni presenti in questa versione sono 5:

  • namedtuple()
  • deque
  • Counter
  • OrderedDict
  • defaultdict

namedtuple()

namedtuple non è una propria e vera collection. Più precisamente è una factory-function il cui scopo è istanziare delle particolari subclassi di tuple i cui field sono accessibili come property.

Es:

Supponiamo di voler rappresentare punti nelle 3 dimensioni mediante tuple.

Normalmente, nella versione più semplice, scriveremmo un codice del tipo:

pt1 = (0,0,0)
pt2 = (1,2,1)
pt3 = (2,2,2)
for pt in (pt1,pt2,pt3):
    print 'x=%s'% pt[0], 'y=%s' % pt[1], 'z=%s' % pt[2]

Per avere una informazione maggiormente strutturata abbiamo due possibilità:

  • Soluzione lunga: Creare la classe Point e dichiarare gli attributi x,y,z come @property eventualmente
  • Soluzione breve: Utilizzare una namedtuple!
Ecco come:
from collections import namedtuple
Point = namedtuple('Point', 'x y z')
pt1 = Point(0,0,0)
pt2 = Point(1,2,1)
pt3 = Point(2,2,2)
for pt in (pt1,pt2,pt3):
    print 'x=%s'% pt.x, 'y=%s' % pt.y, 'z=%s' % pt.z

 

Ovviamente i casi d'uso sono diversi, su una classe Point sarebbe utile creare operatori ad hoc e tutta l'algebra di riferimento, ma l'esempio rende l'dea :)

 

deque

Una collezione che si comporta come una lista estremamente ottimizzata per l'utilizzo come pila / coda.
Supporta insert / pop rapidi ad entrambe le estremità con metodi del tipo: append, appendleft, extend, exdendleft, pop, popleft, rotate, ecc...
La deque è istanziata semplicemente passandole un iteratore al costruttore
 
from collections import deque
iterable =  (1,2,3,4)
queue = deque(iterable)

Counter

Una collezione che agisce come un dizionario dove i valori sono memorizzati come chiave e le occorrenze come valore. Utile per "contare" le occorrenze di oggetti hashable
from collections import Counter
c = Counter('precipitevolissimevolmente')
print c
>>> Counter({'e': 5, 'i': 4, 'm': 2, 'l': 2, 'o': 2, 'p': 2, 's': 2, 't': 2, 'v': 2, 'c': 1, 'n': 1, 'r': 1})
 

OrderedDict

Most-wanted in assoluto sopperisce all'utilizzo di librerie terze tipo StableDict.
Un dizionario in cui viene mantenuto l'ordine di inserimento.
 

defaultdict

Una collezione che agisce con un dizionario ma con una eccezione. Tramite un callable è possibile specificare un valore di default quando un elemento non viene trovato nel dizionario
from collections import defaultdict
# Creiamo un dizionario il cui elemento di default è una lista
list_dict = defaultdict(list)
list_dict['k1'] = 'v'
print list_dict['k1']
>>> v
print list_dict['k2']
>>> []
# Creiamo un dizionario il cui elemento di default è 'Nada' 
list_dict = defaultdict(lambda: 'Nada')
list_dict['k1'] = 'v'
print list_dict['k1']
>>> v
print list_dict['k2']
>>> 'Nada'

In realtà le possibiltà offerte dalle singole collection vanno ben oltre questi semplici esempi.

La documentazione Python è ovviamente il punto di partenza per ogni esplorazione!

Buon viaggio!

Share this on

Share |

On same topics

Commenti

comments powered by Disqus