Optælling af antallet af forekomster af hvert element i en liste med Pythons tæller

Forretning

I Python kan antallet af alle elementer i en liste eller tupel fås ved hjælp af den indbyggede funktion len(), og antallet af hvert element (antallet af forekomster af hvert element) kan fås ved hjælp af metoden count().

Desuden kan Counter-klassen i Python-standardbibliotekets samlinger bruges til at hente elementerne i rækkefølge efter antallet af forekomster.

I dette afsnit vil vi drøfte følgende

  • Tæller det samlede antal elementer:len()
  • Tæl antallet af hvert element (antallet af forekomster af hvert element):count()
  • Anvendelse.collections.Counter
  • Elementerne hentes i rækkefølge efter hyppighed af forekomst:most_common()
  • Tæller antallet (typen) af ikke-overlappende elementer (unikke elementer).
  • Tæller antallet af elementer, der opfylder betingelsen.

Desuden forklares følgende som et konkret eksempel med en kodeeksempel.

  • Tæller antallet af forekomster af et ord i en streng.
  • Tæller antallet af forekomster af et tegn i en streng.

Eksemplet er en liste, men den samme behandling kan udføres med tupler.

Tæl det samlede antal elementer: len()

Hvis du vil tælle det samlede antal elementer i en liste eller tupel, skal du bruge den indbyggede funktion len().

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

print(len(l))
# 7

Optælling af antallet af hvert element (antallet af forekomster af hvert element): count() metoden

Hvis du vil tælle antallet af hvert element (antallet af forekomster af hvert element), skal du bruge count()-metoden for lister, tupler osv.

Hvis en værdi, der ikke findes som et element, overføres som et argument, returneres 0.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

print(l.count('a'))
# 4

print(l.count('b'))
# 1

print(l.count('c'))
# 2

print(l.count('d'))
# 0

Hvis du ønsker at få antallet af forekomster af hvert element på én gang, er følgende collection.Counter nyttig.

Sådan bruger du collections.Counter

Python-standardbibliotekets samlinger har en Counter-klasse.

Counter() er en underklasse af ordbogstypen dict, som har data i form af elementer som nøgler og forekomster som værdier.

import collections

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

c = collections.Counter(l)
print(c)
# Counter({'a': 4, 'c': 2, 'b': 1})

print(type(c))
# <class 'collections.Counter'>

print(issubclass(type(c), dict))
# True

Hvis et element angives som nøgle, kan antallet af elementer fås. Hvis der angives en værdi, der ikke findes som et element, returneres 0.

print(c['a'])
# 4

print(c['b'])
# 1

print(c['c'])
# 2

print(c['d'])
# 0

Du kan også bruge metoder af ordbogstypen, f.eks. keys(), values(), items() osv.

print(c.keys())
# dict_keys(['a', 'b', 'c'])

print(c.values())
# dict_values([4, 1, 2])

print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])

Disse metoder returnerer objekter af typen dict_keys osv. De kan bruges som sådan, hvis du vil køre en for-anvisning. Hvis du ønsker at konvertere dem til en liste, skal du bruge list().

Opkrævning af elementer i rækkefølge efter hyppighed af forekomst: most_common()-metoden

Counter har metoden most_common(), som returnerer en liste over tupler af formen (element, antal forekomster) sorteret efter antallet af forekomster.

print(c.most_common())
# [('a', 4), ('c', 2), ('b', 1)]

Det element med det højeste antal forekomster kan fås ved at angive et indeks, f.eks. [0] for det højeste antal forekomster og [-1] for det laveste antal forekomster. Hvis du kun ønsker at få vist elementerne eller kun antallet af forekomster, kan du angive indekset yderligere.

print(c.most_common()[0])
# ('a', 4)

print(c.most_common()[-1])
# ('b', 1)

print(c.most_common()[0][0])
# a

print(c.most_common()[0][1])
# 4

Hvis du ønsker at sortere dem i rækkefølge efter faldende antal forekomster, skal du bruge skiven med en stigning på -1.

print(c.most_common()[::-1])
# [('b', 1), ('c', 2), ('a', 4)]

Hvis argumentet n er angivet for metoden most_common(), returneres kun de n elementer med det højeste antal forekomster. Hvis det udelades, returneres alle elementer.

print(c.most_common(2))
# [('a', 4), ('c', 2)]

Hvis du ønsker en separat liste over elementer\occurrences ordnet efter antallet af forekomster i stedet for en tupel af (element, antal forekomster), kan du dekomponere den på følgende måde

values, counts = zip(*c.most_common())

print(values)
# ('a', 'c', 'b')

print(counts)
# (4, 2, 1)

Den indbyggede funktion zip() bruges til at transponere en todimensionel liste (i dette tilfælde en liste af tupler) og derefter udpakke og udtrække den.

Tæller antallet (typen) af ikke-overlappende elementer (unikke elementer).

Hvis du vil tælle, hvor mange ikke-overlappende elementer (unikke elementer) der er i en liste eller tupel (hvor mange typer der er), skal du bruge Counter eller set() som beskrevet ovenfor.

Antallet af elementer i Counter-objektet er lig med antallet af ikke-overlappende elementer i den oprindelige liste, som kan fås med len().

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)

print(len(c))
# 3

Du kan også bruge set(), konstruktøren for sættypen set, hvilket er nemmere, hvis du ikke har brug for et Counter-objekt.

Sættetypen er en datatype, der ikke har duplikerede elementer. Når en liste overføres til set(), ignoreres duplikerede værdier og returnerer et objekt af typen set med kun unikke værdier som elementer. Antallet af elementer af denne type fås ved len().

print(set(l))
# {'a', 'c', 'b'}

print(len(set(l)))
# 3

Tæller antallet af elementer, der opfylder betingelsen.

Hvis du vil tælle antallet af elementer i en liste eller tupel, der opfylder en bestemt betingelse, skal du bruge list comprehension notation eller generatorudtryk.

Som et eksempel kan du tælle antallet af elementer med negative værdier for følgende liste af tal

l = list(range(-5, 6))
print(l)
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

Anvendelse af et betinget udtryk på hvert element i list comprehension notation giver en liste, hvis elementer er boolske bools (sand, falsk). Den boolske type bool er en underklasse af den heltalsmæssige type int, hvor sandt behandles som 1 og falsk som 0. Derfor kan antallet af sande værdier (antallet af elementer, der opfylder betingelsen) tælles ved at beregne summen ved hjælp af sum().

print([i < 0 for i in l])
# [True, True, True, True, True, False, False, False, False, False, False]

print(sum([i < 0 for i in l]))
# 5

Hvis vi erstatter [] i list comprehension notationen med (), får vi et generatorudtryk. List comprehension-notationen genererer en liste over alle de behandlede elementer, mens generatorudtrykket behandler elementerne sekventielt og derfor er mere hukommelseseffektivt.

Når generatorudtrykket er det eneste argument, kan () udelades, så det kan skrives som i det sidste tilfælde.

print(sum((i < 0 for i in l)))
# 5

print(sum(i < 0 for i in l))
# 5

Hvis du vil tælle antallet af falske værdier (antallet af elementer, der ikke opfylder betingelsen), skal du bruge not. Bemærk, at > har højere prioritet end not (det beregnes først), så parenteserne () i (i < 0) i det følgende eksempel er ikke nødvendige.

print([not (i < 0) for i in l])
# [False, False, False, False, False, True, True, True, True, True, True]

print(sum(not (i < 0) for i in l))
# 6

Naturligvis kan selve betingelserne ændres.

print(sum(i >= 0 for i in l))
# 6

Nedenfor er vist nogle andre eksempler.

Eksempel på beregning af antallet af ulige elementer for en liste af tal.

print([i % 2 == 1 for i in l])
# [True, False, True, False, True, False, True, False, True, False, True]

print(sum(i % 2 == 1 for i in l))
# 6

Eksempel på en betingelse for en liste af strenge.

l = ['apple', 'orange', 'banana']

print([s.endswith('e') for s in l])
# [True, True, False]

print(sum(s.endswith('e') for s in l))
# 2

Tæller bruges til at tælle på grundlag af antallet af forekomster. items() henter en tupel af (element, antal forekomster), og antallet af forekomster angiver betingelsen.

Følgende er et eksempel på at udtrække elementer med to eller flere forekomster og tælle det samlede antal forekomster. I dette eksempel er der fire a'er og to c'er, hvilket giver i alt seks.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)

print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])

print([i for i in l if c[i] >= 2])
# ['a', 'a', 'a', 'a', 'c', 'c']

print([i[1] for i in c.items() if i[1] >= 2])
# [4, 2]

print(sum(i[1] for i in c.items() if i[1] >= 2))
# 6

Følgende er et eksempel på at udtrække typerne af elementer med to eller flere forekomster og tælle antallet af forekomster. I dette eksempel er der to typer, a og c.

print([i[0] for i in c.items() if i[1] >= 2])
# ['a', 'c']

print([i[1] >= 2 for i in c.items()])
# [True, False, True]

print(sum(i[1] >= 2 for i in c.items()))
# 2

Tæller antallet af forekomster af et ord i en streng.

Som et konkret eksempel kan vi tælle antallet af forekomster af et ord i en streng.

Først erstattes unødvendige kommaer og punktummer med en tom streng ved hjælp af replace()-metoden, og derefter slettes de unødvendige kommaer og punktummer. Brug derefter metoden split() til at oprette en liste, der er adskilt af mellemrum.

s = 'government of the people, by the people, for the people.'

s_remove = s.replace(',', '').replace('.', '')

print(s_remove)
# government of the people by the people for the people

word_list = s_remove.split()

print(word_list)
# ['government', 'of', 'the', 'people', 'by', 'the', 'people', 'for', 'the', 'people']

Hvis du kan lave en liste, kan du få det antal gange hvert ord optræder, hvilke typer ord der optræder, og du kan bruge most_common() i collections.Counter til at få det ord, der optræder flest gange.

print(word_list.count('people'))
# 3

print(len(set(word_list)))
# 6

c = collections.Counter(word_list)

print(c)
# Counter({'the': 3, 'people': 3, 'government': 1, 'of': 1, 'by': 1, 'for': 1})

print(c.most_common()[0][0])
# the

Ovenstående er en meget simpel proces, så det er bedre at bruge biblioteker som NLTK til mere kompleks naturlig sprogbehandling.

I tilfælde af japansk tekst kan split() heller ikke bruges til at opdele teksten, fordi der ikke er nogen klar ordadskillelse. Du kan f.eks. bruge Janome-biblioteket til at opnå dette.

Tæller antallet af forekomster af et tegn i en streng.

Da strenge også er en sekvenstype, kan de bruges med count()-metoden eller overføres som et argument til konstruktøren af collections.Counter().

s = 'supercalifragilisticexpialidocious'

print(s.count('p'))
# 2

c = collections.Counter(s)

print(c)
# Counter({'i': 7, 's': 3, 'c': 3, 'a': 3, 'l': 3, 'u': 2, 'p': 2, 'e': 2, 'r': 2, 'o': 2, 'f': 1, 'g': 1, 't': 1, 'x': 1, 'd': 1})

Eksempel på at finde de 5 hyppigst forekommende tegn.

print(c.most_common(5))
# [('i', 7), ('s', 3), ('c', 3), ('a', 3), ('l', 3)]

values, counts = zip(*c.most_common(5))

print(values)
# ('i', 's', 'c', 'a', 'l')