2016-10-04 5 views
1

Je travaille avec bigrams et unigrams.Impossible d'accéder aux éléments dans une liste en Python

Mes bigrammes sont un compteur de tuples et mes unigrammes sont une liste, où

uni['some key']=count 

Je suis en train de faire le follwing

for b,countB in bigrams.most_common() 
     key=b[0] # this is guaranteed to be a key for my unigrams 
     uniCount=uni[key] 

L'erreur suivante se produit:

TypeError: tuple indeces must be integers or slices, not str 

Je suis confus. Pourquoi cela devrait-il être un problème? uni est essentiellement un hachage, ses valeurs clés sont des chaînes. Comment puis-je accéder à [clé]?

edit: code complet

# corpus is a string containing my corpus 
sp=corpus.split() 

uni={} 
for t in sp: 
     try: 
      uni[t]+=1 
     except: 
      uni[t]=0 
prev='' 
big=[] 
for t in sp: 
     tup=(prev,t) 
     big.append(tup) 
     prev=t 

bigrams=collections.Counter(big) 

for b,countB in bigrams.most_common(): 
     key=b[0] 
     uniCount=uni[key] 
+0

Qu'est-ce que vous obtenez lorsque vous faites 'print ("{}" Format (clé)) 'juste après' key = b [0] '? – Samundra

+2

Besoin de plus de code; selon l'erreur, il semble que votre 'uni' soit un' tuple' alors que vous prétendez qu'il s'agit d'un 'dict'. – tzaman

+0

En fait l'instruction "mes unigrams sont une liste" est en conflit avec l'exemple 'uni ['une clé'] = count'. Les listes ne peuvent pas non plus être indexées de cette façon. – jez

Répondre

1

J'ai essayé votre code et j'ai obtenu un KeyError: '' qui arrive parce que votre bigram initial a une chaîne vide à la position 0 et '' ne se trouve pas dans votre dictionnaire unigrams. Je n'ai pas vu un TypeError donc cela peut être d'ailleurs dans votre code.

Cela dit, d'autres commentaires:

  1. Vous semblez comprendre ce qu'est un collections.Counter fait, mais vous êtes au hasard en essayant de le faire vous-même lors de la construction uni - vous pouvez remplacer votre premier morceau de code avec:

    unigrams = Counter(sp)

  2. Vous pouvez utiliser zip pour itérer sur des paires et construire vos bigrams cette façon, au lieu de bricolage en boucle, ce qui a LSO se débarrasse de votre '' question:

    bigrams = Counter(zip(sp, sp[1:]))

donc votre code devient:.

sp = corpus.split() 
unigrams = Counter(sp) 
bigrams = Counter(zip(sp, sp[1:])) 

for bigram, count in bigrams.most_common(): 
    # etc. 
+0

Je ne comprends pas complètement votre deuxième point. – basil

+0

@basil 'zip' itère sur plusieurs séquences et produit des paires. 'sp [1:]' est le deuxième élément de la même liste. Donc 'zip (sp, sp [1:])' produit tous vos tuples bigram (au lieu de construire manuellement 'big' dans votre deuxième boucle). J'ai ajouté un lien de documentation pour 'zip 'dans le message principal. – tzaman

3

Vous faites l'erreur d'utiliser un tuple quand vous avez besoin peut-être un dictionnaire. En tant qu'état du message d'erreur, les tuples ne peuvent pas être indexés par une clé de chaîne - vous devez utiliser des index numériques. Un dict vous permettra d'utiliser les clés de chaîne comme vous le souhaitez.

d = {} 
d['some key] = 23 

Votre code mis à jour donne une bien meilleure idée de ce que vous faites. Vous commencez par créer un dict du nombre de mots dans uni. Je pense que la ligne qui lit

uni[t] = 0 

devrait en effet lire

uni[t] = 1 

parce que quand cette branche est exécutée, vous détectez la première occurrence d'un mot. Ensuite, vous créez une liste de tuples bigram dans big, puis vous comptez ces bigrams.

Je suis un peu perdu avec la boucle for finale, cependant, où b sera la clé d'un élément Counter et countB être le comte. Donc, key sera le premier mot du bigramme, et uniCount sera le nombre de fois que ce mot est apparu dans le corpus. Après avoir établi ces valeurs, vous continuez à ne rien faire avec eux et vous passez au bigram le plus courant.

Peut-être qu'il est temps de faire un peu d'impression dans cette boucle finale? Le code tel que publié autrement semble raisonnable.

+0

Je ne suis pas sûr si ma terminologie est correcte. Je fais l'erreur d'essayer de résoudre un problème en utilisant une langue que je ne connais pas trop. J'ai ajouté plus de code ci-dessus. – basil

+0

Mise à jour avec une analyse plus complète de votre code étendu. – holdenweb

+0

Notez également, comme mentionné dans d'autres réponses, que votre premier bigram a actuellement la chaîne vide comme premier élément, et cela peut causer des problèmes si c'est l'un des bigrams les plus courants ... (comme cela pourrait être dans un court corpus). – holdenweb

0

J'ai exécuté votre code avec corpus = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore" puisque vous avez dit l'erreur était liée à un uni être un tuple mais il est en fait un dictionnaire.

L'erreur que je suis arrivé est différent, il est un KeyError sur uniCount=uni[key] parce que vous créez une liste de tuples (previous word, word) et le premier mot de corpus mot précédent a défini comme une chaîne vide (prev='' est l'état initial).

La clé à la ligne uniCount=uni[key] est égal au premier élément du tuple (key=b[0]) afin qu'il n'y a pas '' clé dans le dictionnaire uni il jette un KeyError.

Vous voudrez peut-être obtenir le mot, pas le mot précédent du tuple pour être la clé utilisée dans uni.