На этом шаге мы рассмотрим использование функции enumerate().
Вы хотите проитерировать по последовательности и при этом хранить информацию о том, какой по счету элемент сейчас обрабатывается.
Встроенная функция enumerate() изящно справляется с этой задачей:
>>> my_list = ['a', 'b', 'c'] >>> for idx, val in enumerate(my_list): print(idx, val) 0 a 1 b 2 c
Для печати вывода с привычными номерами строк (то есть с нумерацией, начинающейся с 1, а не с 0) вы можете передать соответствующий аргумент start:
>>> my_list = ['a', 'b', 'c'] >>> for idx, val in enumerate(my_list, 1): print(idx, val) 1 a 2 b 3 c >>>
Этот прием особенно полезен для учета номеров строк в файлах, если нужно будет вывести номер строки в сообщении об ошибке:
def parse_data(filename): with open(filename, 'rt') as f: for lineno, line in enumerate(f, 1): fields = line.split() try: count = int(fields[1]) ... except ValueError as e: print('Line {}: Parse error: {}'.format(lineno, e))
Функция enumerate() удобна, например, для отслеживания смещения (offset) в списке для вхождений определенных значений. Так что если вы хотите отобразить слова в файле к строкам, в которых они встречаются, это легко сделать с помощью enumerate() - функция отображает каждое слово на смещение строки в файле, где оно найдено:
word_summary = defaultdict(list) with open('myfile.txt', 'r') as f: lines = f.readlines() for idx, line in enumerate(lines): # Создает список слов в текущей строке words = [w.strip().lower() for w in line.split()] for word in words: word_summary[word].append(idx)
Если вы выведете word_summary после обработки файла, это будет словарь (default dict, если быть точными), и каждое слово будет ключом.
Значение каждого ключа - список номеров строк, где встретилось это слово. Если слово встретилось дважды в одной строке, этот номер строки будет записан в
список дважды, что делает возможным получение разнообразных простых метрик текста.
enumerate() - симпатичное решение для ситуаций, где вы могли бы склоняться к использованию собственной переменной-счетчика. Вы могли бы написать такой код:
lineno = 1 for line in f: # Обработка строки . . . . lineno += 1
Но часто более элегантным (и менее подверженным ошибкам) способом становится использование enumerate():
for lineno, line in enumerate(f): # Обработка строки . . . .
Значение, возвращаемое функцией enumerate(), является объектом enumerate. Это итератор, который последовательно возвращает кортежи, состоящие из счетчика и значения, возвращаемого вызовом функции next() для последовательности, которую вы обходите.
Стоит отметить, что иногда можно запутаться при применении enumerate() к последовательности кортежей, которые при этом распаковываются:
data = [(1, 2), (3, 4), (5, 6), (7, 8)] # Верно! for n, (x, y) in enumerate(data): . . . . # Ошибка! for n, x, y in enumerate(data): . . . .
На следующем шаге мы рассмотрим одновременное итерирование по нескольким последовательностям.