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 mybag0 - (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')]