|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
[Python]Gestione output liste e dizionari
Ciao, ho appena iniziato a guardare un po' python e mi sto facendo un programmino per calcolarmi la media pesata dei voti universitari.
Codice:
#! /usr/bin/python
from collections import defaultdict
...
#Main
dummyMarks=defaultdict(list) #Creates a dictionary of list
fp=open('voti.txt','r')
for line in fp:
dummy1=line.split('\t')
dummyMarks[dummy1[0]].append(dummy1[1:len(dummy1)-1])
#Print marks in alphabetical order
dummyKeys=dummyMarks.keys()
dummyKeys.sort()
for k in dummyKeys:
print '%s: %s' %(k, dummyMarks[k])
...
Come si può vedere, nel 'main' ho creato un dizionario di liste in cui carico i voti presi da un file di testo opportunatemente formattato: Codice:
NomeCorso \t Peso \t Voto \t DataRegistrazione\n Codice:
Nome Corso: [['Peso', 'Voto']] Come prima cosa ho pensato che era necessario mettere i valori ( quindi peso e voto ) dentro una lista tramite dummyMarks.values() Ho provato a guardare su internet: http://www.decalage.info/en/python/print_list Il guaio è che i miei voti alcuni sono interi, altri sono stringhe ( ad esempio 30 Lode ) e non ho trovato una soluzione valida. Inoltre trovo veramente macchinoso gestire l'output di questi dati ( Liste, Dizionari ), ma forse si tratta di inesperienza. Sto pensando che forse fare una classe dalla quale poi creo un oggetto voto che mi tiene il nome del corso, il voto e il peso venga più facile. Ma ancora devo vedere come si costruiscono le classi. Per ora ho fatto solo programmazione modulare. Una piccola nota: Al di là della gestione dell'output, trovo veramente fantastico python. In 2 giorni ho fatto da 0 questo programmino, riuscendo a leggere da file e cacciare dentro le variabili i dati in maniera corretta. Mi viene da ridere se penso di doverlo fare in C... Un'ulteriore nota: Non mi è chiaro come funziona la dichiarazione di variabili. Non esiste una funzione principale ( il caro e vecchio main? ) dove dichiarare le variabili? Le variabili sono tendenzialmente sempre globali ( come nel mio caso )? Non è un abuso? E i passaggi per riferimento non esistono immagino, dato che da quel che ne so i puntatori non esistono, come si ovvia a questo problema (?) ?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Leuven
Messaggi: 667
|
Prova a mettere questo nel for, non ho provato ma credo che funzioni.
Codice:
print '%s: %s,%s' % (k,str(dummyMarkers[k][0]),str(dummyMarkers[k][1])) Il file e' il main in pratica ma puoi fare una cosa del genere: Codice:
If __name__ == '__main__':
Codice...
Per le variabili basta che non dichiari variabili in giro per il codice ma solo localmente dove ti servono. Un po' come nei linguaggi funzionali... Ricordati inoltre che puoi passare funzioni come parametro ad altre funzioni e rendere eseguibile una classe in cui definisci il metodo __call__()! Sembra un po'macchinoso all'inizio ma una votla che ci prendi mano vai liscio come l'olio Ah! Se dividi il programma su piu' file ricordati che le variabili che definisci in un file non sono visibili negli altri e soprattutto una variabile e' visibile solo dal codice che le sta sotto!
__________________
L'elettronica digitale non esiste, è solo elettrotecnica con interruttori piccoli!
|
|
|
|
|
|
#3 | ||||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Codice:
IndexError: list index out of range Quote:
Quote:
Quote:
Cioè se definisco fuori da una funzione ma sotto, una variabile, questa non è accessibile dalla funzione?? Codice:
def funzione(): return 0 variabile=0
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||||
|
|
|
|
|
#4 | ||||||||||||||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Se non usi fp.close() alla fine, lasciando che sia Python a chiudere il file quando non viene più referenziato, puoi scrivere questo: Codice:
for line in open('voti.txt'):
Questo perché un file è un oggetto che può essere "iterato", e ti restituisce una alla volta tutte le righe (ovviamente dev'essere un file di testo). Inoltre non serve specificare il tipo di accesso, 'r', perché è il default. Se non t'interessa l'ultimo valore (o, in generale, gli ultimi valori) di una sequenza (tupla, lista, stringhe, ecc.), puoi usare questa espressione: Codice:
dummy1[1 : -1] Ovviamente con -2 scarta gli ultimi due, ecc. Se t'interessa scorrere gli elementi di dizionario ordinandoli, puoi usare la funzione built-in sorted, e quindi il tuo for diventerà: Codice:
for k in sorted(dummyKeys): Quote:
Con la print di sopra, tu stampi tutti i voti di uno specifico corso, che non sono singoli valori, ma più valori. Dunque dovresti, per ogni corso, stampare (ordinamente, come chiedi sotto) tutti i loro elementi. Ad esempio: Codice:
for k in sorted(dummyKeys):
print k + ':'
for Peso, Voto in dummyKeys[k]:
print ' ', Voto, Peso
Quote:
Esempio: controlla il voto, e se è '30 Lode' memorizzi la tupla (30, ' Lode'), altrimenti memorizzi la tupla (int(Voto), ''). In questo modo hai convertito i valori in una struttura (tupla di due valori) che consente di essere ordinata mettendo alla fine i 30 e lode. In fase di stampa, ti basterà il seguente codice: Codice:
Voto, Lode = tupla print str(voto) + Lode Quote:
Quote:
Le classi preferisco utilizzarle quando devo esprimere una relazione fra oggetti. Come "contenitori" preferisco i dizionari. Quote:
Quote:
Quote:
Quote:
Quote:
Codice:
def f(): return 8.5, 'Monti', [1, 1, 2, 3, 5] OttoEMezzo, Vampiro, Fibo = f() Quote:
Quote:
E' comodissimo perché, ad esempio, se lo lanci come programma principale puoi eseguire una batteria di test per controllare che le funzioni e/o classi in esso definite funzioni. Oppure, più semplicemente, perché il modulo ti offre una serie di funzionalità che sono comode da usare dall'esterno. Ad esempio se hai scritto un modulo che calcola equazioni di primo grado, secondo grado, ecc., lanciandolo come programma principale puoi selezionare il tipo di equazione da risolvere, passargli i parametri da linea di comando, e visualizzare il risultato. Quote:
Ma è roba estremamente potente. Ad esempio l'ultima applicazione del metodo speciale __call__ che ho scritto mi consente di fare questo: Codice:
Service = JSONBin.Service('http://127.0.0.1:8080/WSGI/POST/')
Service.Test(JSONBin.BinaryStringResource('y', 'filename.py', 'Prova! \x80'), x = 1)
Test è un'API esposta dal server, e che accetta un certo numero di parametri in formato JSON (+Bin Come vedi, chiamare quest'API del server è esattamente come invocare un metodo a cui passi gli eventuali parametri. Sarà poi la classe, internamente, a intercettare la chiamata, prendere l'API, costruire opportunamente l'URL (ma si può ottimizzare lasciando aperta la connessione HTTP ed eseguendo altre richieste), impacchettare i parametri passati in formato JSON (+Bin), spedirli al server, leggere il response, e restituirlo al chiamante. Semplicissimo da usare, ma l'implementazione non è nemmeno complicata (anzi!) per chi ha imparato queste funzionalità. Con Python ci si può sbizzarrire molto, come vedi. Quote:
Codice:
def funzione(): return variabile variabile=0 print funzione() # Stampa 0 Codice:
def funzione(): return variabile print funzione() # Genera un'eccezione perché non trova variabile variabile=0
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||||||||||||||
|
|
|
|
|
#5 | ||||||||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quote:
Devo ancora prenderci la mano.. Quote:
Tipo, faccio un esempio C-style: variabile -> Nessun indice Vettore -> [i] Matrice -> [i][j] Matrice 3d -> [i][j][k] ecc... Finendo con il mettere liste dentro liste dentro dizionari perdo il senso di quanto 'a fondo' sono andato... Quote:
Quote:
Il problema sarà quando dovrò fare la media. Ma per controllare una stringa mi basta fare Codice:
if stringa == '30 Lode': ... Quote:
Quote:
Quote:
Perchè dovrei usare quell'if?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||||||||
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Bene o male ho finito il programma.
Una domanda: siccome tra gli esami ho dovuto escludere un esame che non faceva media ( per il quale non c'è nemmeno un voto, ma solo un superato ), per farlo ho fatto: Codice:
dummyMarks=defaultdict(list) #Creates a dictionary of list
fp=open('voti.txt') #If not specified, file is opened in read mode
for line in fp:
dummy1=line.split('\t')
if 'sup' not in line: #Remove english exam, not required for mean
dummyMarks[dummy1[0]].append(dummy1[1:-1]) #Exclude the date with dummy1[1:-1]
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#7 | ||||||||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
Comunque, sì, è questione di abitudine. Quote:
L'unico problema che vedo qui, è che bisogna comprendere che si stanno usando due liste: quella principale, e quelle che sono contenute in ogni suo elemento. Chiarito questo, diventa tutto più facile. Quote:
Quote:
Quote:
Quote:
Però può essere utile capire se un modulo è stato eseguito (quindi come "main") oppure semplicemente importato. Perché è importante distinguere fra le due cose? Perché posso incapsulare il codice di testing del modulo direttamente al suo interno, ma voglio che sia eseguito esclusivamente quando il modulo viene fatto girare come applicazione e non quando è importato. Se mettessi alla fine del modulo l'istruzione EseguiTest(), questa verrebbe chiamata sempre, sia che il modulo sia eseguito come applicazione, sia che venga importato. Se invece scrivo: Codice:
if __name__ == '__main__': EseguitTest() Quando lo importo io voglio soltanto che mi metta a disposizione le sue funzioni, classi, e altro. Non voglio che venga eseguito codice di test. Quote:
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||||||||
|
|
|
|
|
#8 | ||||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quello che disapprovo di questi linguaggi di alto livello è che spesso riesci a fare le cose senza capire a fondo cosa stai facendo. Quote:
Codice:
for k in sorted(dummyMarks): #Print marks in alphabetical order print k,':'; for peso, voto in dummyMarks[k]: print ' Voto:',voto, 'Peso: ',peso Quote:
Quote:
E quindi come faccio a dirgli di matchare la stringa come parola intera?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||||
|
|
|
|
|
#9 | ||||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
Non lo uso mai, per cui ho scambiato i due caratteri. Quote:
Ma il punto è che un modulo può anche essere usato per importare delle funzionalità, e in questo caso non deve fare niente. Se, però, vuoi testarlo, puoi anche lanciarlo come programma, e in questo caso deve "attivarsi". Con quel controllo che è stato riportato puoi verificare se è stato importato o lanciato come programma, e comportarsi di conseguenza. Quote:
Codice:
if line != 'sup':
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||||
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
No ma così il controllo è fatto sull'intera stringa. Io in line ho NomeCorso Peso Voto Data ( è un'unica stringa ) E quello che voglio fare io è cercare all'interno di questa stringa se come parola intera c'è 'sup'.
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Ho capito adesso. Ecco qui:
Codice:
if 'sup' not in line.split(): Siccome una lista è una sequenza, con l'operatore "in" puoi cercare se un elemento (nella sua interezza) vi appartiene; e con "not in" se non vi appartiene.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Eccellente!
Esiste un reference manual tipo il K&R per C ma di Python dove siano indicate tutte le funzioni standard? Una cosa concisa con prototipo della funzione, piccola descrizione e magari un esempio. La guida di python va bene, ma spesso si perde in cose che non mi interssano e ci metto molto a trovare ciò che mi serve. Uguale a cercare su internet. Per evitare che il print vada a capo ad esempio ho trovato soluzioni di non so quante righe di codice e mi pareva IMPOSSIBILE che python potesse fare molte cose ma cadesse su una banalità come questa... Anche questa cosa dello split, se avessi avuto in mano un manuale la risolvevo in fretta senza nemmeno chiedere
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Dentro l'installazione di Python, per lo meno con Windows, è presente un file in formato CHM, che contiene tutto: tutorial, guida, libreria di riferimento, e... molto altro.
E' comodissimo perché puoi fare velocemente delle ricerche, e trovare tutto quello ti serve. Ad esempio, se cerchi print, e poi selezioni statement, trovi la sintassi e la descrizione completa, che riporta anche il funzionamento della virgola usata come ultimo carattere. Diciamo che è la bibbia di Python.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Da me si chiama python272.chm. Controlla la tua versione di Python, e vedi se c'è un file "equivalente".
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#16 |
|
Member
Iscritto dal: May 2010
Messaggi: 157
|
A volte però con la doc mi trovo scomodo, perchè non ti dice tutto tutto.
Qualche volta le cose te le devi cercare facendo dei test. Ad esempio la conversione di un oggetto in intero tramite int() funziona con le stringhe a meno che la stringa in questione non rappresenti un numero (es: 'abc'), nel qual caso genera una eccezione. Nella doc questo non viene detto, ma sopratutto non viene detto che eccezione lancia. |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Comunque è vero che la documentazione non copre sempre bene tutti gli aspetti del linguaggio o della libreria. Preferirei, tra l'altro, che vi fossero più esempi, specialmente per le caratteristiche più avanzate. In ogni caso con qualche rapida ricerca in genere si trova proprio tutto (specialmente su StackOverflow).
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
|
#18 | ||
|
Member
Iscritto dal: May 2010
Messaggi: 157
|
Quote:
Se faccio: help(int()) mi da: Quote:
|
||
|
|
|
|
|
#19 |
|
Member
Iscritto dal: May 2010
Messaggi: 157
|
Sulla doc della 2.6 è come dice cdmauro, dalla 2.7 in poi invece è stata cambiata.
|
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Sì, c'è differenza fra la docstring restituita dalla funzione help, e la documentazione standard (nel mio caso presa dal file chm).
P.S. Uso Python 2.7.2.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:16.




















