Scrivere e leggere valori

Abbiamo detto che si possono inserire valori nelle bag con la sintassi a parentesi quadre come si farebbe con un dizionario, ma esistono due metodi specifici e più espressivi per andare a riempire una Bag. setItem e getItem`.

Il metodo setItem prende come primo parametro la label o path (se parliamo di Bag gerarchica) e secondo parametro il valore. Rispetto all’accesso con le parentesi quadre questo metodo consente di scrivere contestualmente anche gli attributes come kwargs (parametri nominati).

>>> mybag = Bag()
>>> mybag.setItem('italy',None, population=60795612, language='Italian', capital='Rome')
>>> mybag.setItem('italy.regions.lombardy',Bag(), population=10001496, capital='Milan')
>>> mybag.setItem('italy.regions.tuscany',Bag(), population=3749430, capital='Florence')
>>> regions = mybag.getItem('italy.regions')
>>> lom_bag = regions.getItem('lombardy')
>>> tus_bag = regions['tuscany']
>>> tus_bag.setItem('cities.florence', None, populaltion=381678)

Se stampo mybag ottengo questo

>>> print mybag
0 - (Bag) italy: <capital='Rome' language='Italian' population='60795612'>
    0 - (Bag) regions:
        0 - (Bag) lombardy: <capital='Milan' population='10001496'>

        1 - (Bag) tuscany: <capital='Florence' population='3749430'>
            0 - (Bag) cities:
                0 - (None) florence: None  <populaltion='381678'>

Posizionamento in scrittura

Ogni volta che scrivo un valore in una bag con la sintassi a parentesi quadre o con setItem. Il valore viene aggiunto in coda, come ultimo elemento della bag a cui appartiene (Ricordate che la Bag strutturalmente è costituita da una lista di BagNode).

Ma in realtà è possibile specificare la posizione dell’elemento che stiamo scrivendo tra i suoi fratelli, usando il parametro opzionale _position

Questi sono i valori ammessi da _position e i loro significati.

Attribute Description
'<' Inserisce il valore come primo elemento della Bag
'>' Inserisce il valore come ultimo elemento della Bag
'<label' Inserisce il valore prima di un altro specificato
'>label' Inserisce il valore dopo un altro specificato
'<#index' Inserisce il valore prima di una posizione specificata numericamente
'>#index' Inserisce il valore dopo una posizione specificata numericamente
'#index' Inserisce il valore ad una di posizione specificata numericamente

Esempi

>>> mybag = Bag()
>>> mybag['a'] = 1
>>> mybag['b'] = 2
>>> mybag['c'] = 3
>>> mybag['d'] = 4
>>> print mybag
0 - a: 1
1 - b: 2
2 - c: 3
3 - d: 4
>>> mybag.setItem('e',5, _position= '<')
>>> mybag.setItem('f',6, _position= '<c')
>>> mybag.setItem('g',7, _position= '<#3')

Posizionamento in lettura

Abbiamo detto che la Bag è un contenitore ordinato, vediamo quindi come si può leggere un valore per indice numerico anziché tramite label. Se la Bag è gerarchica posso usare la notazione numerica per ogni livello.

>>> mybag = Bag()
>>> mybag['north_america'] = 'NA'
>>> mybag['#0']
'NA'
>>> mybag['europe.nations.italy'] = 'IT'
>>> mybag['europe.nations.#0']
'IT'
>>> mybag['#1.nations.#0']
'IT'
>>> mybag['#1.#0.#0']

Chiavi replicate

Abbiamo detto che rispetto al dizionario la Bag supporta le chiavi replicate.

>>> beatles = Bag()
>>> beatles.setItem('member','John')
>>> beatles.setItem('member','Paul')
>>> beatles.setItem('member','George')
>>> beatles.setItem('member','Ringo')

Però se andiamo a controllare la nostra Bag beatles…

>>> print beatles
0 - (str) member: Ringo

Infatti per aggiungere elementi con la stessa label occorre usare addItem

>>> beatles = Bag()
>>> beatles.setItem('member','John')
>>> beatles.addItem('member','Paul')
>>> beatles.addItem('member','George')
>>> beatles.addItem('member','Ringo')
>>> print beatles
0 - (str) member: John
1 - (str) member: Paul
2 - (str) member: George
3 - (str) member: Ringo

Il metodo digest

Se vogliamo leggere ora non singoli valori o attributi possiamo usare il medoto digest, il quale ritorna una list di tuple che possono includere - Chiavi - Valori - Attributi - Uno specifico attributo

Presi trasversalmente da tutti i nodi della bag, con le seguenti sintassi.

Sintassi Risultato
'#k' La label di ciascun nodo
'#v' Il value di ciascun nodo
'#v.path' Un valore interno a partire da ciascun nodo
'#a' Gli attributi di un ciascun nodo
'#a.attributeName' Un attributo in particolare di ciascun nodo
>>> print b['documents.letters'].digest('#k,#a.createdOn,#a.createdBy')
[('letter_to_sheila', '12-4-2003', 'Walter'), ('letter_to_mark', '10-7-2003', 'Jack'), ('letter_to_john', '11-5-2003', 'Mark')]

In questo esempio abbiamo chiesto:

  • le label con #k
  • Gli attributi createdOn con #a.createdOn
  • Gli attributi createdOn con #a.createdBy

C’è anche un modo di invocare il metodo digest con la sintassi delle parentesi quadre. Bisogna aggiungre dopo il path il carattere ? seguito da d: e poi la consueta codifica della digest in tabella.

>>> print b['documents.letters.?d:#k,#a.createdOn,#a.createdBy']
[('letter_to_sheila', '12-4-2003', 'Walter'), ('letter_to_mark', '10-7-2003', 'Jack'), ('letter_to_john', '11-5-2003', 'Mark')]
>>> print b['documents.letters.?d:#v,#a.createdOn']
[('file0', '10-7-2003'), ('file1', '11-5-2003'), ('file2', '12-4-2003')]