2011-11-28 23 views
7

Sono un principiante Python che tenta di analizzare un file per creare una tabella di allocazioni di memoria. Il mio file di input è nel seguente formato:Dizionario Python con variabili come chiavi

48 bytes allocated at 0x8bb970a0 
24 bytes allocated at 0x8bb950c0 
48 bytes allocated at 0x958bd0e0 
48 bytes allocated at 0x8bb9b060 
96 bytes allocated at 0x8bb9afe0 
24 bytes allocated at 0x8bb9af60  

Il mio primo obiettivo è quello di fare una tabella che conta le istanze di un particolare numero di allocazioni di byte. In altre parole, la mia uscita desiderata per l'ingresso di cui sopra sarebbe qualcosa di simile:

48 bytes -> 3 times 
96 bytes -> 1 times 
24 bytes -> 2 times 

(per ora, io non sono preoccupato per gli indirizzi di memoria)

Dal momento che sto usando Python, ho pensato fare questo usando un dizionario sarebbe la strada giusta da percorrere (basandosi su circa 3 ore di lezione per leggere tutorial di Python). È una buona idea?

Nel tentativo di farlo utilizzando un dizionario, ho deciso di impostare il numero di byte "chiave" e un contatore come "valore". Il mio piano era di incrementare il contatore su ogni occorrenza della chiave. A partire da ora, il mio frammento di codice è il seguente:

# Create an empty dictionary 
allocationList = {} 

# Open file for reading 
with open("allocFile.txt") as fp: 
    for line in fp: 
     # Split the line into a list (using space as delimiter) 
     lineList = line.split(" ") 

     # Extract the number of bytes 
     numBytes = lineList[0]; 

     # Store in a dictionary 
     if allocationList.has_key('numBytes') 
      currentCount = allocationList['numBytes'] 
      currentCount += 1 
      allocationList['numBytes'] = currentCount 
     else 
      allocationList['numBytes'] = 1 

for bytes, count in allocationList.iteritems() 
    print bytes, "bytes -> ", count, " times" 

Con questo, ottengo un errore di sintassi nella 'has_key' chiamare, che mi porta a chiedersi se è ancora possibile utilizzare le variabili come chiavi di dizionario. Tutti gli esempi che ho visto finora presuppongono che le chiavi siano disponibili in anticipo. Nel mio caso, posso ottenere le mie chiavi solo quando sto analizzando il file di input.

(Si noti che il mio file di input può essere eseguito in migliaia di linee, con centinaia di chiavi diverse)

Grazie per tutto l'aiuto che potete fornire.

+0

come ti vedo citato 'numBytes', quindi, si è sempre riferendo costante – dmitry

+0

e omesso due punti in righe dopo 'se allocationList.has_key ('numBytes')' e 'else' - dovrebbe essere Errore di sintassi – dmitry

risposta

10

L'apprendimento di una lingua riguarda tanto la sintassi e i tipi di base quanto la libreria standard. Python ha già una classe che rende molto semplice il tuo compito: collections.Counter.

from collections import Counter 

with open("allocFile.txt") as fp: 
    counter = Counter(line.split()[0] for line in fp) 

for bytes, count in counter.most_common(): 
    print bytes, "bytes -> ", count, " times" 
+0

Sento che la tua risposta è più vera di chiunque altro qui –

+2

+1: Se sei interessato solo al conteggio, 'Counter' è la strada da percorrere. D'altra parte, l'OP ha scritto: * per ora, non sono preoccupato per gli indirizzi di memoria * --- suppongo che potrebbe prima o poi avere bisogno di una soluzione personalizzata che vada oltre "Counter". –

+0

Grazie mille per questa soluzione. L'ho provato, ma non ha funzionato. Questo perché Counter è disponibile solo per Python> 2.7, e sto usando 2.6.4. Ma mi ha portato a: http://stackoverflow.com/questions/3594514/how-to-find-most-common-elements-of-a-list, e qui ho trovato un modo per risolvere il mio problema. Ma sto contrassegnando questa risposta come la soluzione, perché questo è probabilmente il modo migliore per risolvere il problema. – Gautam

4

Il metodo di Dictionnary dict.has_key() ha disappeared in python3, per sostituirlo, utilizzare la in parola chiave:

if numBytes in allocationList: # do not use numBytes as a string, use the variable directly 
    #do the stuff 

ma nel tuo caso, è anche possibile sostituire tutto il

if allocationList.has_key('numBytes') 
      currentCount = allocationList['numBytes'] 
      currentCount += 1 
      allocationList['numBytes'] = currentCount 
     else 
      allocationList['numBytes'] = 1 

con una linea con get:

allocationList[numBytes] = allocationList.get(numBytes, 0) + 1 
+2

Non è necessario impostare il valore due volte utilizzando 'setdefault'; usa invece 'dict.get'. –

+0

@FerdinandBeyer: hai ragione, è stato un po 'eccessivo e inutile usare setdefault. –

+0

Rimosso 'has_key' e usato 'in'. Grazie per il consiglio. Probabilmente stavo leggendo alcuni tutorial obsoleti. – Gautam

1

Sicuramente puoi usare le variabili come chiavi dict. Tuttavia, hai una variabile chiamata numBytes, ma stai utilizzando una stringa contenente il testo "numBytes" - stai usando una costante di stringa, non la variabile. Ciò non causerà l'errore, ma è un problema. Invece, provare:

if numBytes in allocationList: 
    # do stuff 

Inoltre, si consideri un Counter. Questa è una classe conveniente per gestire il caso che stai guardando.

4

si ottiene un errore di sintassi, perché vi manca il colon alla fine di questa linea:

if allocationList.has_key('numBytes') 
            ^

Il tuo approccio è bene, ma potrebbe essere più facile da usare dict.get() con un valore di default:

allocationList[numBytes] = allocationList.get(numBytes, 0) + 1 

Poiché il tuo allocationList è un dizionario e non un elenco, potresti voler scegliere un nome diverso per la variabile.

+0

Grazie. Non avevo idea di ":". Ho appena capito che ne ho bisogno anche uno alla fine della mia dichiarazione "per". – Gautam

Problemi correlati