2013-12-12 12 views
5

Ich bin eine gültige JSON-Datei (verschachtelt 5 Ebenen tief) lesen, dann das Hinzufügen einiger Daten, die ihm, und anschließend diese Daten für einige Berechnungen zu verwenden versuchen.Random „int ist nicht subscriptable“ Verhalten

Ich erhalte int is not subscriptable Fehler in zufälliger Weise. Ich kann meinen Kopf nicht darum wickeln. Hilfe zu str() Gießen nicht, den Druck mit pprint es nicht zu lindern, zu int() auf Eingang Gießen auch nicht hilft. Ich bin aus Optionen verzweifelt läuft ...

Hauptfunktion

with open(rNgram_file, 'r', encoding='utf-8') as ngram_file: 
    data = json.load(ngram_file) 
    data = rank_items(data) 
    data = probability_items(data) 

rank_items (Daten)

Alle Werte in der 5-verschachtelten Ebene gezählt, und fügte hinzu, im Baum nach oben arbeiten. Ich habe die int() Umwandlung in die Eingabe als eine mögliche Lösung hinzugefügt, aber das hat nicht geholfen. Das Problem tritt mit dem x_grams['_rank']

for ngram, one_grams in data.items(): 
     ngram_rank = 0 
     for one_gram, two_grams in one_grams.items(): 
      one_gram_rank = 0 
      [..] 
       for four_gram, values in four_grams.items(): 
       # 4gram = of, values = 34 
       three_gram_rank += values 
       four_grams['_rank'] = int(three_gram_rank) 
       two_gram_rank += three_gram_rank 
      [..]  
      two_grams['_rank'] = int(one_gram_rank) 
      ngram_rank += one_gram_rank 
     one_grams['_rank'] = int(ngram_rank) 

probability_items (Daten) immer

Dies ist, wo die Fehler auftreten. Scheinbar zufällig, wird es über int is not subscriptable beschweren, wo x_rank oder x_grams['rank] gedruckt oder zugewiesen werden, auch wenn sie mit type() ausgewertet werden (was, wenn es funktioniert, sagt <class 'int'>) Ich markierte die häufigsten Zeilen mit einem Kommentar unten. Seltsam genug, Linie 2 und 3 niemals eine Ausnahme auslösen ...

for ngram, one_grams in data.items(): 
     ngram_rank = int(one_grams['_rank'])    # never gives an error 
     print("NgramRank: ", str(ngram_rank))    # never gives an error 
     if ngram != '_rank': 
      for one_gram, two_grams in one_grams.items(): 
       pprint(type(two_grams['_rank']))    # common error point 
       one_gram_rank = str(two_grams['_rank'])  # never reaches this 
       if one_gram != '_rank': 
        for two_gram, three_grams in two_grams.items(): 
         pprint(type(three_grams['_rank'])) # common error point 
         pprint(str(three_grams['_rank'])) # never reaches this 
         two_gram_rank = str(three_grams['_rank']) 
         [..] 
        one_gram_prob = int(one_gram_rank)/int(ngram_rank) 
        two_grams['_prob'] = one_gram_prob 
      ngram_prob = int(ngram_rank)/int(ngram_rank) 
      one_grams['_prob'] = ngram_prob 

In randowm Art und Weise, eine Ausnahme auf dem gemeinsamen Fehlerpunkt oben geworfen wird. Aufgrund dieser Ausnahmen werden die folgenden Zeilen nie erreicht. Wenn Sie jedoch die allgemeinen Fehlerpunkte löschen, werden die Zeilen darunter zu den Fehlerpunkten. Und manchmal Es macht einen vollen Lauf durch den ganzen Weg in die Innen-for-Schleife, Druck <class 'int'> wenn ausgewertet und alle, bis sie an einer Ausnahme hält.

Ich habe keine Ahnung, was passiert ist, ich weiß nicht einmal verstehen, wie diese Fehler auftreten können, wenn ich es bin Auswertung mit Type()

Da dies ein seltsamen Problem, und ich bin offensichtlich einen seltsamen Fehler zu machen , ich habe den gesamten Code in einem Kern hier: https://gist.github.com/puredevotion/7922480

Hoffnung jemand helfen kann!

Traceback Details

['Traceback (most recent call last):\n', ' File "Ngram_ranking.py", line 121, in probability_items\n pprint(type(four_grams[\'_rank\']))\n', "TypeError: 'int' object is not subscriptable\n"] 

*** extract_tb: 
[('Ngram_ranking.py', 121, 'probability_items', "pprint(type(four_grams['_rank']))")] 

*** format_tb: 
[' File "Ngram_ranking.py", line 121, in probability_items\n pprint(type(four_grams[\'_rank\']))\n'] 

*** tb_lineno: 121 
Exception in on line 121: pprint(type(four_grams['_rank'])): 'int' object is not subscriptable 

Traceback für die Linie 115

['Traceback (most recent call last):\n', ' File "Ngram_ranking.py", line 115, in probability_items\n pprint(type(three_grams[\'_rank\']))\n', "TypeError: 'int' object is not subscriptable\n"] 

*** extract_tb: 
[('Ngram_ranking.py', 115, 'probability_items', "pprint(type(three_grams['_rank']))")] 

*** format_tb: 
[' File "Ngram_ranking.py", line 115, in probability_items\n pprint(type(three_grams[\'_rank\']))\n'] 

*** tb_lineno: 115 
Exception in on line 115: pprint(type(three_grams['_rank'])): 'int' object is not subscriptable 

PPRINT (Daten) an der Spitze der probability_items (Daten)

{'aesthetic': {'_rank': 290, 
      'feeling': {'_rank': 10, 
         'the': {'_rank': 10, 
           'feeling': {'_rank': 10, 'of': 10}}}, 
      'perception': {'_rank': 280, 
          'and': {'_rank': 190, 
            'the': {'_rank': 190, 
              'design': 15, 
              'environment': 5, 
              'music': 100, 
              'painting': 15, 
              'work': 5, 
              'works': 50}}, 
          'of': {'_rank': 90, 
           'the': {'_rank': 50, 
             'work': 30, 
             'world': 20}, 
           'their': {'_rank': 40, 'female': 40}}}}} 
+0

Können Sie vollständige Stacktrace geben? – thefourtheye

+0

@thefourtheye bearbeitet den Beitrag, jetzt mit Tracebacks (entlehnt den tb-Code von: http://docs.python.org/3.3/library/traceback.html) – puredevotion

+0

Vorschlag: jedes Mal, wenn Sie 'pprint (type (x_grams ['_ rank']))' Sie setzen es mit 'pprint (type (x_grams))' nur um zu überprüfen, welcher Typ 'x_grams' ist, bevor Sie versuchen, zu subskribieren es. Es scheint, als gäbe es einen Platz im Code, wo Sie einem der 'x_gramms'-Werte einen int zuweisen, wo Sie nur ein Diktat zuweisen wollen, aber es ist nicht klar, wo. –

Antwort

4

Das Problem besteht darin, dass Sie ein verschachteltes Wörterbuch auf mehreren Ebenen haben und den gleichen Code für alle drei Ebenen replizieren, obwohl die Verschachtelung etwas anders ist.

Ich werde nur einen Teil Ihres Wörterbuch nehmen

{ 
'aesthetic': 
    { 
    '_rank': 290, 
    'feeling': 
     { 
     '_rank': 10, 
     'the': 
      { 
      '_rank': 10, 
      'feeling': 
       { 
       '_rank': 10, 
       'of': 10 
       } 
      } 
     }, 
    } 
} 

Ihr Top-Level-Wörterbuch einheitlich als Wert ist (für Schlüssel aesthetic) ist immer ein Wörterbuch. Aber die unteren Ebenen haben auch ints als einige ihrer Werte.

Wenn Sie also tun

for ngram, one_grams in data.items(): 

Sie haben ngram=aesthetics und one_grams={the dictionary}

int(one_grams['_rank']) 

wird immer funktionieren (als der Wert Wörterbuch, das Element hat _rank. So können Sie nie hier einen Fehler.

Jetzt gehen wir zum nächsten Schritt

one_gram, two_grams in one_grams.items() 

Lauf .items() für one_grams Wörterbuch gibt

(one_gram,two_grams) = [('_rank', 290), ('feeling', {'_rank': 10, 'the': {'_rank': 10, 'feeling': {'_rank': 10, 'of': 10}}})] 

Hinweis two_grams ein int für den ersten Eintrag und ein dict für die zweite. Da Sie über den gesamten Artikel() durchlaufen, während

tun
two_grams['_rank'] 

Sie laufen in den Fehler (die Ihnen sagt, dass Sie einen int getroffen haben, wenn dict erwartet wurde). Das gleiche Problem tritt in den inneren Schleifen auf.

Da keine Wörterbücher bestellt werden, können items() in beliebiger Reihenfolge zurückgegeben werden. Somit kann _rank das erste Element oder unter anderen Wörterbuchelementen sein. In diesem Fall steigen Sie in die inneren for loops ab und stoßen dort auf das gleiche Problem.

können Sie _rank Schlüssel vernachlässigen während

for one_gram,two_grams one_grams.items(): 
    if one_gram=='_rank': 
     continue 

in allen Schleifen iterieren.

+0

Obwohl ich dies schon mit 'if ngram! = '_rank' abgedeckt hatte:' aber eindeutig nicht. Danke vielmals! – puredevotion

+1

@puredevotion Schau es dir so an: Irgendwann in der Schleife 'für ein_gramm, two_grams in one_gramms.items():' wirst du feststellen, dass 'one_gram'' '_rank'' ist und' two_grams' ein int. Aber du nennst 'pprint (type (two_grams ['_ rank']))' bevor du überhaupt nachprüfst, ob es so ist. –