Contagem do número de ocorrências de cada elemento de uma lista com o Contador Python

O negócio

Em Python, o número de todos os elementos de uma lista ou tuple pode ser obtido usando a função integrada len(), e o número de cada elemento (o número de ocorrências de cada elemento) pode ser obtido usando o método count().

Além disso, a classe Contadora das colecções da biblioteca padrão Python pode ser utilizada para obter os elementos em ordem do número de ocorrências.

Nesta secção, discutiremos o seguinte

  • Contar o número total de elementos:len()
  • Contar o número de cada elemento (o número de ocorrências de cada elemento):count()
  • Utilização.collections.Counter
  • Os elementos são recuperados por ordem de frequência de ocorrência:most_common()
  • Contar o número (tipo) de elementos não sobrepostos (elementos únicos).
  • Contar o número de elementos que satisfazem a condição.

Além disso, como exemplo concreto, explica-se o seguinte com o código da amostra.

  • Conta o número de ocorrências de uma palavra numa cadeia.
  • Contar o número de ocorrências de um personagem numa cadeia.

A amostra é uma lista, mas o mesmo processamento pode ser feito com tuplos.

Conte o número total de elementos: len()

Para contar o número total de elementos de uma lista ou tuple, utilizar a função len() integrada.

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

print(len(l))
# 7

Contagem do número de cada elemento (o número de ocorrências de cada elemento): método de contagem()

Para contar o número de cada elemento (o número de ocorrências de cada elemento), utilizar o método de contagem() para listas, tuplos, etc.

Se um valor que não existe como elemento é passado como argumento, 0 é devolvido.

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

Se quiser obter o número de ocorrências de cada elemento de uma só vez, a seguinte colecção.contador é útil.

Como utilizar as colecções.contador

As colecções da biblioteca padrão Python têm uma classe de contador.

Counter() é uma subclasse do tipo dicionário ditado, que tem dados sob a forma de elementos como chaves e ocorrências como valores.

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

Se um elemento for especificado como uma chave, o número de elementos pode ser obtido. Se for especificado um valor que não existe como elemento, é devolvido 0.

print(c['a'])
# 4

print(c['b'])
# 1

print(c['c'])
# 2

print(c['d'])
# 0

Também pode usar métodos do tipo dicionário, tais como chaves(), valores(), itens(), etc.

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)])

Estes métodos devolvem objectos do tipo dict_keys, etc. Podem ser utilizados como estão, se se quiser executar uma declaração. Se quiser convertê-lo para uma lista, use list().

Obtenção de elementos por ordem de frequência de aparecimento: método most_common()

O contador tem o método most_common(), que devolve uma lista de tuplos da forma (elemento, número de ocorrências) ordenados pelo número de ocorrências.

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

O elemento com o maior número de ocorrências pode ser obtido especificando um índice, tal como [0] para o maior número de ocorrências e [-1] para o menor número de ocorrências. Se quiser obter apenas os elementos ou apenas o número de ocorrências, pode especificar ainda mais o índice.

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

Se quiser ordená-los por ordem decrescente de ocorrências, utilize a fatia com o incremento definido para -1.

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

Se o argumento n for especificado para o método most_common(), apenas os n elementos com o maior número de ocorrências são devolvidos. Se for omitido, todos os elementos são devolvidos.

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

Se quiser uma lista separada de ocorrências ordenadas pelo número de ocorrências, em vez de um tuple de (elemento, contagem de ocorrências), pode decompô-la da seguinte forma

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

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

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

A função zip() integrada é utilizada para transpor uma lista bidimensional (neste caso, uma lista de tuplos), e depois desempacotar e extrair a mesma.

Contar o número (tipo) de elementos não sobrepostos (elementos únicos).

Para contar quantos elementos não sobrepostos (elementos únicos) existem numa lista ou tuple (quantos tipos existem), usar Counter ou set() como descrito acima.

O número de elementos no objecto contador é igual ao número de elementos não sobrepostos na lista original, que pode ser obtido com len().

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

print(len(c))
# 3

Também pode usar set(), o construtor do conjunto tipo set, o que é mais fácil se não precisar de um objecto contador.

O tipo de conjunto é um tipo de dados que não tem elementos duplicados. Passar uma lista para definir() ignora os valores duplicados e devolve um objecto de tipo definido apenas com valores únicos como elementos. O número de elementos deste tipo é obtido por len().

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

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

Contar o número de elementos que satisfazem a condição.

Para contar o número de elementos de uma lista ou tuple que satisfazem uma determinada condição, utilizar notação de compreensão de lista ou expressões geradoras.

Como exemplo, conte o número de elementos com valores negativos para a seguinte lista de números

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

A aplicação de uma expressão condicional a cada elemento da notação de compreensão de lista produz uma lista cujos elementos são bools booleanos (verdadeiros, falsos). O bool tipo booleano é uma subclasse do tipo int inteiro, onde verdadeiro é tratado como 1 e falso como 0. Portanto, o número de valores verdadeiros (o número de elementos que satisfazem a condição) pode ser contado através do cálculo da soma usando a soma().

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

Se substituirmos [] na notação de compreensão da lista por (), obtemos uma expressão geradora. A notação de compreensão de lista gera uma lista de todos os elementos processados, enquanto a expressão geradora processa os elementos sequencialmente e é, portanto, mais eficiente em termos de memória.

Quando a expressão geradora é o único argumento, () pode ser omitida, por isso pode ser escrita como neste último caso.

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

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

Se quiser contar o número de valores falsos (o número de elementos que não satisfazem a condição), não utilize. Note que > tem uma precedência maior do que não (é calculado primeiro), por isso os parênteses () em (i < 0) no exemplo seguinte não são necessários.

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

É claro que as próprias condições podem ser alteradas.

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

Alguns outros exemplos são mostrados abaixo.

Exemplo de obtenção do número de elementos ímpares para uma lista de números.

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

Exemplo de uma condição para uma lista de cordas.

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

O contador é utilizado para contar com base no número de ocorrências. itens() recupera um tuple de (elemento, número de ocorrências), e o número de ocorrências especifica a condição.

O seguinte é um exemplo de extracção de elementos com duas ou mais ocorrências e contagem do número total de ocorrências. Neste exemplo, há quatro a's e dois c's, para um total de seis.

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

Segue-se um exemplo de extracção dos tipos de elementos com duas ou mais ocorrências e contagem do número de ocorrências. Neste exemplo, existem dois tipos, a e 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

Conta o número de ocorrências de uma palavra numa cadeia.

Como exemplo concreto, vamos contar o número de ocorrências de uma palavra numa corda.

Primeiro, substituir as vírgulas e pontos desnecessários por um fio vazio usando o método substituir(), e depois apagá-los. Depois, utilizar o método split() para criar uma lista separada por espaços.

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']

Se conseguir fazer uma lista, pode obter o número de vezes que cada palavra aparece, os tipos de palavras que aparecem, e o mais_comum() das colecções.

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

O processo acima é muito simples, por isso é melhor utilizar bibliotecas como a NLTK para um processamento mais complexo da linguagem natural.

Também, no caso do texto japonês, split() não pode ser usado para dividir o texto porque não há uma separação clara de palavras. Por exemplo, pode utilizar a biblioteca Janome para o conseguir.

Contar o número de ocorrências de um personagem numa cadeia.

Como as cordas são também um tipo de sequência, podem ser utilizadas com o método count() ou passadas como argumento para o construtor de colecções.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})

Exemplo de recuperação dos 5 primeiros caracteres mais frequentemente ocorridos.

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')
Copied title and URL