Это очень странный способ организовать вещи. Если вы сохранили в словаре, это просто:
# 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
Этот код для обновления словаря счетчиков является обычным «шаблоном» в Python. Это настолько распространено, что существует специальная структура данных defaultdict
, созданная, чтобы сделать это еще проще:
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
Если вы обращаетесь к, defaultdict
используя ключ, и ключ еще не находится в defaultdict
, ключ автоматически добавляется со значением по умолчанию. Объект defaultdict
принимает переданный вами вызываемый объект и вызывает его для получения значения по умолчанию. В этом случае мы прошли в класс int
; при вызове Python int()
возвращает нулевое значение. Итак, при первой ссылке на URL-адрес его счетчик инициализируется нулевым значением, а затем вы добавляете к нему единицу.
Но словарь, полный счетчиков, также является распространенным шаблоном, поэтому Python предоставляет готовый к использованию класс: containers.Counter
вы просто создаете Counter
экземпляр, вызывая класс, передавая любую итерацию; он создает словарь, в котором ключи являются значениями из итерируемого объекта, а значения - это количество раз, когда ключ появлялся в итерируемом объекте. Приведенный выше пример становится таким:
from collections import Counter # available in Python 2.7 and newer
urls_d = Counter(list_of_urls)
Если вам действительно нужно сделать так, как вы показали, самым простым и быстрым способом было бы использовать любой из этих трех примеров, а затем построить тот, который вам нужен.
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()]
Если вы используете Python 2.7 или новее, вы можете сделать это однострочно:
from collections import Counter
urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]
Использование по умолчанию работает, но также:
используя
.get
, вы можете получить возврат по умолчанию, если он не существует. По умолчанию это None, но в случае, если я вам послал, это будет 0.источник
Используйте defaultdict :
источник
У меня это всегда отлично работает:
источник
Делать это именно по-своему? Вы можете использовать структуру for ... else
Но это довольно неэлегантно. Вам действительно нужно хранить посещенные URL-адреса в виде СПИСКА? Если вы отсортируете его как dict, например, проиндексированный по строке url, он будет намного чище:
Несколько замечаний во втором примере:
urls
устраняет необходимость просматривать весьurls
список при тестировании для одногоurl
. Такой подход будет быстрее.dict( )
вместо фигурных скобок делает код корочеlist_of_urls
,urls
и вurl
качестве имен переменных затрудняет анализ кода. Лучше найти что-нибудь более понятное, напримерurls_to_visit
,urls_already_visited
иcurrent_url
. Я знаю, это дольше. Но так понятнее.И, конечно, я предполагаю, что
dict(url='http://www.google.fr', nbr=1)
это упрощение вашей собственной структуры данных, потому что в противном случае этоurls
могло бы быть просто:Что может быть очень элегантно с позой defaultdict :
источник
За исключением первого раза, каждый раз, когда встречается слово, проверка оператора if не выполняется. Если вы считаете большое количество слов, многие, вероятно, будут встречаться несколько раз. В ситуации, когда инициализация значения происходит только один раз, а увеличение этого значения будет происходить во много раз, дешевле использовать оператор try:
вы можете прочитать об этом больше: https://wiki.python.org/moin/PythonSpeed/PerformanceTips
источник