4
votes

Comment compter plusieurs éléments dans une liste

J'ai la liste suivante:

solution = {(x,i) for x[3], i[4] in data}

Les données représentent l'année, le mois, le jour, le jour de la semaine, le nombre.

Je souhaite obtenir un dictionnaire des comptes totaux par jour de la semaine. Quelque chose comme ça

results = {1:200,
           2:0,
           3:20,
           4:0,
           5:0,
           6:0,
           7:40,
}

Je pense que la meilleure façon de faire cela, s'il vous plaît, corrigez-moi si je me trompe, est d'utiliser collections.Counter. J'ai abandonné cet effort pour une compréhension du dictionnaire mais je n'ai pas pu résoudre le problème

data = [[2004,1,1,1,50], [2008,2,28,1,150],[1984,5,1,3,20],[1982,5,1,7,20], [1982,5,8,7,20]]


0 commentaires

4 Réponses :


3
votes

Puisque vous voulez additionner et ne pas compter, il peut être plus facile d'utiliser defaultdict:

data = [[2004,1,1,1,50], [2008,2,30,1,150],[1984,5,1,3,20],[1982,5,1,7,20], [1982,5,8,7,20]]

c = {d: 0 for d in range(1, 8)} # or dict.fromkeys(range(1, 8), 0)
for l in data:
    c[l[3]] += l[4]
print(c)
# {1: 200, 2: 0, 3: 20, 4: 0, 5: 0, 6: 0, 7: 40}

Si vous insistez pour n'avoir aucune entrée, vous pouvez l'instancier avant:

from collections import defaultdict

data = [[2004,1,1,1,50], [2008,2,30,1,150],[1984,5,1,3,20],[1982,5,1,7,20], [1982,5,8,7,20]]

c = defaultdict(int)
c.update({d: 0 for d in range(1, 8)})
for l in data:
    c[l[3]] += l[4]
print(c)
# defaultdict(<class 'int'>, {1: 200, 2: 0, 3: 20, 4: 0, 5: 0, 6: 0, 7: 40})

À ce stade, vous pouvez utiliser un dict normal sur defaultdict si vous êtes sûr que l'entrée n'aura pas de jours invalides:

from collections import defaultdict

data = [[2004,1,1,1,50], [2008,2,30,1,150],[1984,5,1,3,20],[1982,5,1,7,20], [1982,5,8,7,20]]

c = defaultdict(int)

for l in data:
    c[l[3]] += l[4]

print(c)
# defaultdict(<class 'int'>, {1: 200, 3: 20, 7: 40})


1 commentaires

Juste pour noter que vous pouvez créer ici c sans dict-comp , par exemple: c = dict.fromkeys (range (1, 8), 0) < / code> ...



0
votes

Vous pouvez résoudre ce problème avec une simple boucle à la place. Créez un dictionnaire de résultats avec des valeurs initiales pour chaque jour définies sur zéro, et ajoutez-y simplement étape par étape.

results = {k:0 for k in range(1,8)}
#Output: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0}
data = [[2004,1,1,1,50], [2008,2,30,1,150],[1984,5,1,3,20],[1982,5,1,7,20], [1982,5,8,7,20]]

for x in data:
    results[x[3]] += x[4]

print(results)
#Output:
{1: 200, 2: 0, 3: 20, 4: 0, 5: 0, 6: 0, 7: 40}


0 commentaires

1
votes

Si, comme dans vos données d'entrée, vos données sont triées par jour de la semaine, c'est-à-dire que toutes les sous-listes d'un jour de la semaine sont adjacentes, vous pouvez utiliser itertools.groupby avec une compréhension de dictionnaire:

data = sorted(data, key=itemgetter(-2))

Si vos données ne sont pas triées, vous devrez trier par jour de la semaine premier:

from itertools import groupby
from operator import itemgetter

res = {k: sum(map(itemgetter(-1), v)) for k, v in groupby(data, key=itemgetter(-2))}

print(res)
# {1: 200, 3: 20, 7: 40}


0 commentaires

0
votes

Comme vous avez demandé d'utiliser Counter à partir de collections, vous pouvez l'utiliser comme ceci:

from collections import Counter

counter=Counter()

for group in data:
    counter[group[3]] +=group[4]

results=dict(counter)


3 commentaires

sympa, mais Counter sous-classe déjà dict , pas besoin de dict (counter)


Pouvez-vous me dire pourquoi quelque chose comme ça ne fonctionnerait pas, mais le vôtre? importer des collections \ n pour l'élément dans les données: \ n collections.Counter [élément [3] + = élément [4]


collections.Counter est une classe. Vous avez besoin d'une instance de cette classe et utilisez l'instance: "counter = collections.Counter ()". Comme DeepSpace l'a mentionné, Counter est une sous-classe de dict et vous pouvez donc utiliser les crochets pour ajouter des paires clé-valeur: counter [key] = value.