2017-02-02 7 views
2

Entschuldigung, wenn dies zuvor angesprochen wurde. Ich kann keine vorherigen Antworten finden, die mein spezifisches Problem ansprechen, also hier ist es.Verschachtelte Wörterbücher für den Wortzählungscache

Die Übung erfordert, dass der Benutzer einen TXT-Dateinamen eingibt. Der Code nimmt diese Datei und zählt die darin enthaltenen Wörter und erstellt ein Wörterbuch aus Wort: Anzahl Paaren. Wenn die Datei bereits eingegeben wurde und ihre Wörter gezählt wurden, verweist das Programm, anstatt es erneut zu zählen, auf den Cache, in dem seine vorherigen Zählungen gespeichert sind.

Mein Problem ist ein verschachteltes Wörterbuch von Wörterbüchern erstellen - den Cache. Das Folgende habe ich bisher. Im Moment überschreibt jede neue TXT-Datei das Wörterbuch und verhindert, dass es als Cache verwendet wird.

def main(): 

file = input("Enter the file name: ")  #Takes a file input to count the words 

d = {} #open dictionary of dictionaries: a cache of word counts] 

with open(file) as f: 

    if f in d:  #check if this file is in cache. 

     for word in sorted(d[f]):  #print the result of the word count of an old document. 
      print("That file has already been assessed:\n%-12s:%5d" % (word, d[f][word])) 

    else:  #count the words in this file and add the count to the cache as a nested list. 

     d[f] = {}  #create a nested dictionary within 'd'. 

     for line in f:    #counts the unique words within the document. 
      words = line.split() 

      for word in words: 
       word = word.rstrip("!'?.,")  #clean up punctuation here 
       word = word.upper()    #all words to uppercase here 

       if word not in d[f]: 
        d[f][word] = 1 
       else: 
        d[f][word] = d[f][word] + 1 

    for word in sorted(d[f]):  #print the result of the word count of a new document. 
     print("%-12s:%5d" % (word, d[f][word])) 


    main()  #Run code again to try new file. 

main() 
+1

Versuchen Sie, d = {} außerhalb des Bereichs von main() zu deklarieren. – Radan

+1

Sie verwenden f anstelle der Datei. Es bezieht sich auf die gleiche Variable – Marat

+0

Hallo, vielen Dank für Ihre Hilfe. Das Verschieben des d-Wörterbuchs aus der Funktion hat dazu geführt, dass die neuen Wörterbücher ordnungsgemäß verschachtelt wurden. Die Funktion erkennt jedoch nicht, dass dieselbe Datei zweimal eingegeben wird. Die verschachtelten Listen haben das Präfix: "{<_io.TextIOWrapper name = 'filename.txt' mode = 'r' encoding = 'UTF-8'>:" Irgendeine Idee, wie man das anspricht? Danke noch einmal! - Kornman vor 49 Sekunden – grainman

Antwort

1

Einfache Lösung:

d[file] = {} 
.... 
d[file][word] = 1 # and so on 

, denn wenn man f d cahnge [f] auf den gleichen Eintrag bezieht sich nach wie vor in d

Auch können Sie wiederverwenden defaultdict:

from collections import defaultdict 

d = defaultdict(lambda x: defaultdict(int)) 

def count(file): 
    with (open(file)) as f: 
     if file not in d: 
      # this is just list comprehension 
      [d[file][word.rstrip("!'?.,").upper()] += 1 
       for word in line.split() 
        for line in f] 
    return d[file] 

def main(): 
    file = input("Enter the file name: ") 
    count(file) 
    if file in d: 
     print("That file has already been assessed, blah blah") 
    for word in sorted(d[file]):  #print the result of the word count of a new document. 
     print("%-12s:%5d" % (word, d[f][word])) 

if __name__ == "__main__": 
    main()   
+1

das wird es nicht beheben - 'd' wird immer noch neu initialisiert' main() 'heißt – asongtoruin

+1

was ist in dieser Funktion? Es ist nicht im Codebeispiel. – Marat

+1

@asongtoruin sowieso, nur die Antwort aktualisiert, um Haupt hinzuzufügen() – Marat

1

Ihr Problem ist, dass Sie das Diktat neu initialisieren onary bei jedem Anruf main(). Sie müssen es außerhalb der Schleife deklarieren, wobei Sie den Benutzer bitten, einen Dateinamen anzugeben.

from collections import Counter 
import string 
import os.path 

d = {} 

while True: 
    input_file = input("Enter the file name: ") 
    if not os.path.isfile(input_file): 
     print('File not found, try again') 
     continue 

    if d.get(input_file, None): 
     print('Already found, top 5 words:') 
    else: 
     with open(input_file, 'rb') as f: 
      d[input_file] = Counter(f.read().upper().translate(None, string.punctuation).split()) 

    for word, freq in sorted(d[input_file].items(), reverse=True, key=lambda x: x[1])[:5]: 
      print(word.ljust(20) + str(freq).rjust(5)) 

Dieser druckt die Top-5 häufigsten Wörter und deren Frequenzen für eine Datei:

Das Verfahren kann auch ein wenig könnten mit Hilfe der collections.Counter() und string.translate neatened auf. Wenn es die Datei bereits gesehen hat, gibt es eine Warnung als solche. Beispielausgabe:

THE     24 
OF      15 
AND     12 
A      10 
MODEL     9 
Verwandte Themen