2013-12-12 17 views
5

Sto leggendo un file JSON valido (5 livelli nidificati in profondità), quindi aggiungo alcuni dati ad esso, e successivamente cerco di usare quei dati per alcuni calcoli.Casuale "int non è un indice" comportamento

Sto ricevendo gli errori in modo casuale. Non riesco a capirlo. la trasmissione a str() non aiuta, la stampa con pprint non lo allevia, la trasmissione su int() su input non aiuta neanche. Sto disperatamente a corto di opzioni ...

funzione principale

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 (dati)

Tutti i valori si contano a livello 5-nidificato, e ha aggiunto lavorando verso l'alto nell'albero. Ho aggiunto il cast int() all'input come una possibile soluzione, ma ciò non ha aiutato. Il problema si verifica con ottenere i 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 (dati)

Questo è dove si verificano gli errori. Apparentemente a caso, si lamenterà di int is not subscriptable dove x_rank o x_grams['rank] vengono stampati o assegnati, anche se sono valutati con type() (che, se funziona, dice <class 'int'>) Ho segnato le righe più comuni con un commento qui sotto. Stranamente, linea 2 e 3 non sollevare un'eccezione ...

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 

Nella moda randowm, viene generata un'eccezione sul punto di errore comune sopra. A causa di queste eccezioni, le linee sottostanti non vengono mai raggiunte. Ma se si eliminano i punti di errore comuni, le linee sottostanti diventano i punti di errore. E a volte, esegue un ciclo completo in tutto il ciclo interno, stampando <class 'int'> quando viene valutato e tutto, fino a quando non si arresta a un'eccezione.

non ho idea di cosa sta succedendo, non capisco nemmeno come questo errore può verificarsi quando sto valutando con Type()

Dal momento che questo è un problema strano, e sto, ovviamente, facendo uno strano errore , Ho messo tutto il codice in un punto qui: https://gist.github.com/puredevotion/7922480

Spero che qualcuno possa aiutare!Dettagli

TraceBack

['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 per la linea 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 (dati) in cima probability_items (dati)

{'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

Puoi fornire uno stacktrace completo? – thefourtheye

+0

@thefourtheye ha modificato il post, ora con tracebacks (preso in prestito il codice tb da: http://docs.python.org/3.3/library/traceback.html) – puredevotion

+0

Suggerimento: ogni volta che esegui 'pprint (scrivi (x_grams ['_ rank']))' lo precedi con 'pprint (type (x_grams))' solo per verificare che tipo 'x_grams' è prima di provare a pedici esso. Sembra che ci sia un posto nel codice in cui si assegna un int a uno dei valori di 'x_grams' dove si intende solo assegnare un dict, ma non è chiaro dove. –

risposta

4

Il problema è che si dispone di un dizionario nidificato a più livelli e si replica lo stesso codice per tutti e tre i livelli, nonostante la nidificazione sia leggermente diversa.

mi limiterò a prendere un po 'parte del vostro dizionario

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

Il dizionario livello superiore è uniforme come valore (per la chiave aesthetic) è sempre un dizionario. Ma i livelli inferiori hanno anche ints come alcuni dei loro valori.

Così, quando si fare

for ngram, one_grams in data.items(): 

hai ngram=aesthetics e one_grams={the dictionary}

int(one_grams['_rank']) 

funziona sempre (come il dizionario valore ha l'elemento _rank. Quindi, non si ha mai un errore qui.

Ora passiamo al passaggio successivo

one_gram, two_grams in one_grams.items() 

Esecuzione .items() per one_grams dizionario dà

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

Avviso two_grams è un int per la prima voce e un dict per il secondo. Dal momento di eseguire iterazioni su tutto l'articoli() mentre si fa

two_grams['_rank'] 

si esegue in errore (che ti dice che hai raggiunto un int quando dict era previsto). Lo stesso problema si verifica nei loop interni.

Poiché i dizionari non sono ordinati, gli articoli() possono restituire in qualsiasi ordine. Pertanto, _rank potrebbe essere il primo elemento o al di sotto di altri elementi del dizionario. In tal caso, si scende nell'interno per cicli e si incontra lo stesso problema lì.

È possibile trascurare _rank tasti mentre l'iterazione

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

in tutti i cicli.

+0

Ho pensato che fosse già coperto da 'if ngram! = '_rank':' ma chiaramente no. Molte grazie! – puredevotion

+1

@puredevotion Guardalo in questo modo: ad un certo punto del ciclo 'for one_gram, two_grams in one_grams.items():' troverai che 'one_gram' è' '_rank'' e 'two_grams' è un int. Ma tu chiami 'pprint (type (two_grams ['_ rank']))' prima ancora di controllare per sapere se lo è. –

Problemi correlati