contar palavras em texto

2,652 views
Skip to first unread message

Herbert Fortes

unread,
Jun 5, 2016, 5:05:57 PM6/5/16
to Python Brasil
Olá,

Fiz esse script[0] para contar palavras em
um arquivo com texto.

Alguém com tempo livre para dar uma olhada
e fazer comentários ?

[0] - http://paste.debian.net/715756/



abraços,
--
Herbert Parentes Fortes Neto (hpfn)

Eduardo Cuducos

unread,
Jun 6, 2016, 9:37:59 AM6/6/16
to python-brasil

Oi Herbet,

Dei uma olhada aqui, escrevi alguns comentários só pensando no primeiro método, espero que ajude.

Primeira coisa que senti é que tu poderia melhorar os nomes das tuas variáveis e métodos. Comecei a ler a definição sem saber o que erano_inter (no é de número ou de nãointer é de interação? Intercalar? O que a função deveria fazer?). E o que é a? Uma palavra? O número de vezes que ela já aparceu? Não precisa responder as perguntas para mim, mas é só para exemplificar que teu código, com melhores nomes de variáveis, já pode ajudar quem for lê-lo (você daqui a 6 meses, 2 anos, voltando a um projeto por exemplo) a entender o que cada trecho faz.

Lembre-se do Zen do Python (pesquei três versos):

  • Explicit is better than implicit;
  • Readability counts;
  • In the face of ambiguity, refuse the temptation to guess.

Mas indo ao código, à lógica e sintaxe: podemos descobrir se a variável aé vazia ou não de uma forma mais pythônica:

if a:
    return 'Variável `a` existe e não é vazia`

Ou ainda:

if not a:
    return 'Variável `a` (provavelmente) é vazia`

Coloquei provavelmente pois no Python vários valores de a podem cair naquela condicional ali: FalseNone0[] (uma lista vazia)… mas enfim, se saquei a ideia do teu código, acho que não tem problema usarif not ali. Se quiser ler mais sobre essa parte, isso fica nessa parte da documentação do Python: Boolean operations.

Outra coisa é que você usa o dict_w dentro do método, mas ele é definido lá fora. Isso funciona pois quando o Python não acha o objetodict_w dentro do método ele o procura fora. Mas mesmo assim isso pode dar problema. Caso você chame no_inter antes de definirdict_w, teu método quebra, por exemplo. Acho que no futuro, quando você for estudar classes, vai ficar facinho de contornar isso — fique tranquilo. Por agora, se quiser ser mais explícito nisso, acho que vale muito a pena: é só adicionar um global no começo do teu método. Deixando explícito assim, diminui a chance de alguém chamar o no_inter(a) antes de ter definido dict_w, pois a primeira linha do método já fica ali de lembrete. No mais, esse artigo pode te interessar, ele explica como o Python organiza seus objetos.

Por fim, não precisamos iterar com o dicionário para ver se a é uma de suas chaves. Como vi que já usas o in, podemos considerar quedict_w.keys() retorna um objeto iterável. Então podemos usar o incom dict_w.keys(). Ou seja, podemos simplesmento perguntar a in dict_w.keys()?

Com isso, dá eliminar o a.lower() que era chamado duas vezes e, juntando o que comentei antes simplificar teu código:

def no_inter(a):
    global dict_w
    a = a.lower()

    if not a or a in dict_w.keys():
        return 0

    return a

O legal do Python é como ele é fácil para quem sabe inglês. Repare que as duas principais linhas desse código ficam quase parecendo inglês mesmo, e não Python: if not a, or [if] a in dictionary w keys, return zero.

Não tive tempo de comentar o resto do código. Mas espero ter ajudado.

Abraço,

Eduardo Cuducos
http://cuducos.me/


Eduardo Cuducos
http://cuducos.me/

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar

<*> Para visitar o site do grupo na web, acesse:
    http://groups.google.com/group/python-brasil

<*> Para sair deste grupo, envie um e-mail para:
    python-brasi...@googlegroups.com

---
Você está recebendo esta mensagem porque se inscreveu no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Rodrigo Baron

unread,
Jun 6, 2016, 2:52:49 PM6/6/16
to Python Brasil
Um modo mais simples e fácil (sem tratar lower/upper e acentos): 

from collections import defaultdict

text =  "seu texto texto escrito aqui aqui"
word_dict = defaultdict(int)
for word in text.split(' '):
  word_dict[word] += 1

print(word_dict['texto'])

Att,

Renzo Nuccitelli

unread,
Jun 6, 2016, 3:21:07 PM6/6/16
to Python Brasil

Facil mesmo seria o Counter:

from collections import Counter
Counter("seu texto texto escrito aqui aqui".split())

Tb sem tratamento de caracteres ;)


--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.
--
Renzo Nuccitelli

Eu leio email somente uma vez por dia. Se o assunto for urgente, me ligue.


Herbert Fortes

unread,
Jun 6, 2016, 3:29:02 PM6/6/16
to python...@googlegroups.com
Olá,

Obrigado pelos comentários. Acabei de dar
a primeira lida neles.

Amanhã tem mais.

Rodrigo Baron

unread,
Jun 6, 2016, 3:35:21 PM6/6/16
to Python Brasil
hahahaha... fácil ou pronto?

At,

Flávio Casacurta

unread,
Jun 6, 2016, 4:52:55 PM6/6/16
to Python Brasil
Hebert

utilizando o Counter como o Renzo falou mas com tratamento de lower

w = Counter(file(r'seuarquivo.txt').read().lower().split())

[]s

Herbert Fortes

unread,
Jun 7, 2016, 9:50:53 AM6/7/16
to python...@googlegroups.com
O Counter é fantástico.

Abelardo Mota

unread,
Jun 7, 2016, 10:12:32 AM6/7/16
to Python Brasil
Coloquei num notebook algumas das ideias daqui e outras(no estilo 'jeito complicado de fazer', com nltk e scikit-learn), comparando os resultados.

https://github.com/abevieiramota/abevieiramota.github.io/blob/master/notebook/Portuguese%20tokenizer.ipynb

Rayan Sóstenes

unread,
Jun 7, 2016, 7:53:46 PM6/7/16
to Python Brasil
Exatamente a mesma saida que seu código atual, porém mais rápido e em menos linhas:

import string
from collections import Counter

with open('lorem.txt') as file:
    file_contents = file.read().translate(string.maketrans("",""), string.punctuation)

    words = Counter(file_contents.split())

    print(dict(words))
    print("other: {}" .format(words['other']))
    print("pencils: {}" .format(words['pencils']))

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.



--
*Rayan Sóstenes Alves Gama da Motta*
*Analista de Sistemas*
*Graduando em Eng. de Controle e Automação*
*Cel: (62) 8248-4091*

Rayan Sóstenes

unread,
Jun 7, 2016, 8:02:53 PM6/7/16
to Python Brasil
Em 7 de junho de 2016 20:53, Rayan Sóstenes <rayan...@gmail.com> escreveu:
Exatamente a mesma saida que seu código atual, porém mais rápido e em menos linhas:

import string
from collections import Counter

with open('lorem.txt') as file:
    file_contents = file.read().lower().translate(string.maketrans("",""), string.punctuation)

Herbert Fortes

unread,
Jun 8, 2016, 11:12:13 AM6/8/16
to python...@googlegroups.com
On Tue, 7 Jun 2016 20:53:40 -0300
Rayan Sóstenes <rayan...@gmail.com> wrote:

> file_contents = file.read().translate(string.maketrans("",""),
> string.punctuation)
>
> words = Counter(file_contents.split())
>
> print(dict(words))
> print("other: {}" .format(words['other']))
> print("pencils: {}" .format(words['pencils']))

Não está exatamente igual.

Falta a lower(). Até ai tudo bem, fácil de resolver. E
o uso de translate() junto de read() está muito legal
(python2).

Mas tem uma diferença, de um a menos, em 'other' mesmo
assim. Acho que o problema está em 'otherbill:1'. Fazendo
um 'grep' no arquivo tenho 'other--Bill!'.

Em python3, translate aceita apenas um argumento:
in_ = string.punctuation
out_ = len(in_) * ' '

with open('pg11.txt') as f:
# python3
file_contents = f.read().lower().translate(str.maketrans(in_,out_))

Tenho 54. O mesmo resultado de:
cat pg11.txt | tr -s " " "\n" | grep -iw other | wc -l



abraço,

Herbert Fortes

unread,
Jun 9, 2016, 8:27:15 AM6/9/16
to python...@googlegroups.com

Re-edit
Fui ver a documentação. Em python2, translate() aceita
um argumento apenas. Então a linha é praticamente igual:

file_contents = file.read().lower().translate(string.maketrans(in_,out_)) #,string.punctuation)
Reply all
Reply to author
Forward
0 new messages