Essa é uma maneira muito estranha de organizar as coisas. Se você armazenou em um dicionário, é fácil:
# This example should work in any version of Python.
# urls_d will contain URL keys, with counts as values, like: {'http://www.google.fr/' : 1 }
urls_d = {}
for url in list_of_urls:
if not url in urls_d:
urls_d[url] = 1
else:
urls_d[url] += 1
Este código para atualizar um dicionário de contagens é um "padrão" comum em Python. É tão comum que haja uma estrutura de dados especial defaultdict
, criada apenas para tornar isso ainda mais fácil:
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
Se você acessar o defaultdict
usando uma chave e a chave ainda não estiver no defaultdict
, a chave será adicionada automaticamente com um valor padrão. O defaultdict
pega o chamável que você passou e o chama para obter o valor padrão. Nesse caso, passamos na aula int
; quando o Python o chama, int()
ele retorna um valor zero. Portanto, na primeira vez que você faz referência a um URL, sua contagem é inicializada em zero e, em seguida, você adiciona um à contagem.
Mas um dicionário cheio de contagens também é um padrão comum, então Python fornece uma classe pronta para uso: containers.Counter
você apenas cria uma Counter
instância chamando a classe, passando qualquer iterável; ele constrói um dicionário onde as chaves são valores do iterável e os valores são contagens de quantas vezes a chave apareceu no iterável. O exemplo acima então se torna:
from collections import Counter # available in Python 2.7 and newer
urls_d = Counter(list_of_urls)
Se você realmente precisa fazer da maneira que mostrou, a maneira mais fácil e rápida seria usar qualquer um desses três exemplos e construir o que você precisa.
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
urls = [{"url": key, "nbr": value} for key, value in urls_d.items()]
Se você estiver usando o Python 2.7 ou mais recente, poderá fazê-lo em uma linha:
from collections import Counter
urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]
Usar o padrão funciona, mas também:
usando
.get
, você pode obter um retorno padrão se ele não existir. Por padrão, é Nenhum, mas no caso que enviei para você, seria 0.fonte
Use defaultdict :
fonte
Isso sempre funciona bem para mim:
fonte
Para fazer exatamente do seu jeito? Você poderia usar a estrutura for ... else
Mas é bastante deselegante. Você realmente tem que armazenar os urls visitados como uma LISTA? Se você classificá-lo como um dicionário, indexado pela string url, por exemplo, seria muito mais limpo:
Algumas coisas a serem observadas nesse segundo exemplo:
urls
remove a necessidade de passar por toda aurls
lista ao testar um únicourl
. Essa abordagem será mais rápida.dict( )
vez de colchetes torna seu código mais curtolist_of_urls
,urls
eurl
como nomes de variáveis tornar o código muito difícil de analisar. É melhor encontrar algo mais claro, comourls_to_visit
,urls_already_visited
ecurrent_url
. Eu sei, é mais longo. Mas está mais claro.E, claro, estou assumindo que
dict(url='http://www.google.fr', nbr=1)
é uma simplificação da sua própria estrutura de dados, porque, do contrário,urls
poderia ser simplesmente:O que pode ficar muito elegante com a postura defaultdict :
fonte
Exceto pela primeira vez, cada vez que uma palavra é vista, o teste da instrução if falha. Se você estiver contando um grande número de palavras, muitas provavelmente ocorrerão várias vezes. Em uma situação em que a inicialização de um valor só ocorrerá uma vez e o aumento desse valor ocorrerá muitas vezes, é mais barato usar uma instrução try:
você pode ler mais sobre isso: https://wiki.python.org/moin/PythonSpeed/PerformanceTips
fonte