web-dev-qa-db-fra.com

Compter le nombre d'occurrences dans une liste de tuples

Je suis assez nouveau sur Python, mais je n’ai trouvé aucune solution à mon problème.

Je veux compter les occurrences d'une chaîne dans une liste de n-uplets.

Voici la liste des tuples:

list1 = [
         ('12392', 'some string', 'some other string'),
         ('12392', 'some new string', 'some other string'),
         ('7862', None, 'some other string')
        ]

J'ai essayé cela, mais il suffit d'imprimer 0

for entry in list1:
    print list1.count(entry[0])

Comme le même ID apparaît deux fois dans la liste, ceci devrait renvoyer:

2
1

J'ai également essayé d'incrémenter un compteur pour chaque occurrence du même identifiant, mais je ne comprenais pas trop comment l'écrire.

* EDIT: En utilisant la réponse géniale d’Eumiro. Je viens de me rendre compte que je n’expliquais pas tout le problème… j’ai besoin du nombre total d’entrées ayant une valeur supérieure à 1. Mais si j’essaie de faire: 

for name, value in list1:

    if value > 1:
        print value

Je reçois cette erreur:

ValueError: Too many values to unpack
18
mackwerk

Peut-être que collections.Counter pourrait résoudre votre problème:

from collections import Counter
Counter(elem[0] for elem in list1)

résultats

Counter({'12392': 2, '7862': 1})

Il est rapide car il parcourt votre liste une seule fois. Vous parcourez les entrées, puis essayez d’obtenir un nombre de ces entrées dans votre liste. Cela ne peut pas être fait avec .count, mais peut être fait comme suit:

for entry in list1:
    print sum(1 for elem in list1 if elem[0] == entry[0])

Mais sérieusement, jetez un oeil à collections.Counter.

EDIT: J'ai besoin du nombre total d'entrées ayant une valeur supérieure à 1.

Vous pouvez toujours utiliser la variable Counter:

c = Counter(elem[0] for elem in list1)
sum(v for k, v in c.iteritems() if v > 1)

renvoie 2, c’est-à-dire la somme des nombres supérieurs à 1.

30
eumiro

list1.count(entry[0]) ne fonctionnera pas car il regarde chacun des trois n-uplets dans list1, par exemple. ('12392', 'some string', 'some other string') et vérifie si elles sont égales à '12392' par exemple, ce qui n'est évidemment pas le cas.

La réponse de @ eurmiro vous montre comment faire avec Counter (ce qui est le meilleur moyen!) mais voici la version d'un homme pauvre pour illustrer le fonctionnement de Counter à l'aide d'un dictionnaire et de la méthode dict.get(k, [,d]) qui tentera d'obtenir une clé (k), mais s'il n'existe pas, il retourne la valeur par défaut (d):

>>> list1 = [
         ('12392', 'some string', 'some other string'),
         ('12392', 'some new string', 'some other string'),
         ('7862', None, 'some other string')
]
>>> d = {}
>>> for x, y, z in list1:
        d[x] = d.get(x, 0) + 1


>>> d
{'12392': 2, '7862': 1}
4
jamylak

J'avais besoin de fonctionnalités supplémentaires que Counter n'avait pas. J'ai une liste de tuples dont le premier élément est la clé et le second élément est la quantité à ajouter. La solution @jamylak était une excellente adaptation pour cela!

>>> list = [(0,5), (3,2), (2,1), (0,2), (3,4)]

>>> d = {}
>>> for x, y in list1:
    d[x] = d.get(x, 0) + y

>>> d
{0: 7, 2: 1, 3: 6}
0
Mosqueteiro