2010-07-19 9 views
3

J'essaie de compter une liste de nombres entiers. J'ai une liste de nombres dans un fichier csv que je suis capable de lire, qui ressemble à quelque chose comme 4 245,34,99,340, ... Ce que je fais est d'essayer de retourner est un dictionnaire avec la clé: paires de valeurs où la clé est une valeur entière du fichier csv, et la valeur est le nombre de fois qu'il apparaît dans la liste. Je ne sais pas ce que je fais mal ici, toute aide serait appréciéedictionnaire python, en comptant les nombres entiers

allCounts = dict() 

rows = csv.reader(open('...csv'), delimiter=',') 

    for intValue in rows: 
     intVal = intValue[0] 

     for intVal, numAppearances in allCounts: 
      if intVal in allCounts: 
       allCounts[numAppearances] = allCounts[numAppearances]+1 
      else: 
       allCounts[numAppearances] = 1 
+0

Est-ce que ce travail est fait? En outre, quelle est exactement votre valeur de sortie prévue. Vous voulez votre dictionnaire pour chaque ligne du fichier CSV, puis ...? – chryss

+0

non, ce n'est pas des devoirs. Je fais un projet de recherche et en train d'apprendre le python – student

Répondre

8

Sonne comme ce que vous voulez est un objet Compteur:
http://docs.python.org/library/collections.html#counter-objects

Aussi je pense que vous pouvez utiliser la Module CSV:
http://docs.python.org/library/csv.html

Utilisation des modules intégrés devrait le rendre beaucoup plus facile :)

Pour obtenir les lignes de manière mething comme cela devrait fonctionner:

csvfile = open("example.csv") 
dialect = csv.Sniffer().sniff(csvfile.read(1024)) 
csvfile.seek(0) 
reader = csv.reader(csvfile, dialect) 

alors vous devriez être en mesure de le faire:

c = Counter(reader) 
+0

J'aimerais pouvoir vous +1 à deux reprises. – xtofl

5

Ce que vous faites est itérer à travers l'ensemble dict pour chaque cellule, ce qui est un peu bizarre et probablement pas ce que vous voulez faire. Ce que vous voulez vraiment faire, c'est regarder dans la dict et incrémenter la clé en question. Alors:

# first part stays mostly the same 
rows = csv.reader(open("...csv")) 

allCounts = {} 

for row in rows: 
    for field in row: 
     allCounts[field] = allCounts.get(field, 0) + 1 

Cette dernière ligne utilise un peu de fonctionnalité intéressante dict, qui retourne une valeur par défaut si la clé est introuvable.

Dans votre propre code, il y a quelques défauts notables. La plus importante est la quatrième et cinquième lignes. vous extrayez le premier champ de la ligne sélectionnée et l'affectez à intVal mais vous masquez complètement intVal en l'utilisant comme clé lors de l'itération sur votre dict. ce que cela signifie, c'est que cette mission n'a pas fonctionné du tout.

La clause if est vouée à l'échec. Vous vérifiez pour voir si une clé est dans une dict, mais vous êtes venu avec cette clé en itérant sur les touches de la même dict. Bien sûr, cette clé est dans le dict.

Le problème suivant est que votre clause else modifie une collection sur laquelle vous itérez. Python ne fait aucune garantie sur la façon dont cela fonctionnera pour les dicts, alors ne le faites pas

D'ailleurs, il n'y a aucune raison d'itéter sur le dict. Vous pouvez simplement saisir n'importe quelle paire clé-valeur qui vous intéresse directement. Ce que vous devriez répéter est la liste des entiers du fichier. Un fichier CSV est toujours structuré comme une liste de valeurs (normalement séparées par des virgules) formant des lignes, et les lignes sont séparées par des retours à la ligne. le module CSV préserve cette vue en renvoyant une liste de listes. Pour explorer les valeurs réelles, vous devez parcourir chaque ligne, puis chaque champ de cette ligne. Votre code itère sur chaque ligne, puis chaque touche de la dict pour chaque ligne, en ignorant les champs.

+0

Vous pourriez vouloir utiliser 'defaultdict' pour ça, c'est un peu plus simple. –

+0

@ S.Lott: vrai, mais je devrais introduire une nouvelle collection, et je préfère garder le nombre de modules utilisés aussi petit que possible. – SingleNegationElimination

+1

Impossible d'acheter cela aussi terriblement sensible. C'est Python. Presque tout implique une utilisation intensive des bibliothèques. Je pense qu'il est trompeur de fournir un 'dict.get (this, 0)' quand une chose un peu plus simple est disponible. D'autant plus que les informations supplémentaires pourraient aider cette personne à comprendre encore plus comment Python peut résoudre des problèmes comme celui-ci. –

0

Débarrassez-vous de intVal = intValue[0]

Depuis intValue est une chaîne, vous serez le premier caractère de la représentation de chaîne de e numéro de e.Ce que vous voulez vraiment, c'est intValue = int(intValue).

Ensuite, vous avez tout votre logique mal - actuellement allCounts est initialisé à un dictionnaire vide que vous ne pouvez pas parcourir. Ce que vous voulez faire est de parcourir les valeurs retournées par le csv.reader, que vous êtes déjà. De là, votre logique est proche - malheureusement ce n'est ni des fers à cheval ni des grenades à main. Ce que vous voulez, c'est ceci:

# Checks to see if intValue is a key in the dictionary 
if intValue in allCounts: 
    # If it is then we want to increment the current value 
    # += 1 is the idiomatic way to do this 
    allCounts[intValue] += 1 
else: 
    # If it is not a key, then make it a key with a value of 1 
    allCounts[intValue] = 1 
+0

Dans son code, intValue n'est pas un nombre entier. C'est en fait une liste de chaînes, comme renvoyé par 'csv.reader.next' – SingleNegationElimination

+0

ah .. fixé. C'est ce qui arrive quand vous passez trop de temps à regarder une invite IPython, ces guillemets simples disparaissent! –

Questions connexes