В этом уроке мы рассмотрим 6 советов, как лучше писать циклы For
на Python. Эти советы включают в себя простые методы рефакторинга, которые вы можете сразу применить в своем коде.
1) Не используйте циклы вообще
По возможности старайтесь избегать циклов и вместо этого используйте встроенные методы.
Типичным примером является использование встроенного sum()
метода вместо ручного цикла:
numbers = [10, 20, 33, 40, 50, 60, 70, 80] result = 0 for num in numbers: result += num print(result) # 363 # --> Refactor result = sum(numbers) print(result) # 363
2) Используйте перечисление
Когда вам нужно выполнить итерацию по списку, и вам нужен как индекс, так и текущий элемент, вместо этого используйте встроенную enumerate()
функцию:
data = ["a", "b", "c"] for i in range(len(data)): print(i, data[i]) # --> Refactor for idx, val in enumerate(data): print(idx, val) # 0 a # 1 b # 2 c
Он принимает необязательный start
параметр, который начинает подсчет индекса с этого значения.
for idx, val in enumerate(data, start=1): print(idx, val) # 1 a # 2 b # 3 c
3) Используйте zip метод
При переборе нескольких списков используйте zip
. Он возвращает итератор кортежей и останавливается, когда исчерпан самый короткий входной итеративный объект:
a = [1, 2, 3] b = ["a", "b", "c"] for i in range(len(a)): print(a[i], b[i]) # --> Refactor for val1, val2 in zip(a, b): print(val1, val2) # 1 a # 2 b # 3 c
Начиная с Python 3.10, вы можете установить параметр, strict=True
чтобы вызывать ошибки, если одна из итераций короче другой. Это может быть полезно для выявления ошибок в вашей программе.
a = [1, 2, 3] b = ["a", "b", "c", "d"] for val1, val2 in zip(a, b, strict=True): print(val1, val2) # ValueError: zip() argument 2 is longer than argument 1
4) Думайте лениво!
Попробуйте думать лениво и реорганизуйте свой код с помощью генераторов.
Здесь мы используем выражение генератора, которое затем можно присвоить переменной, что помогает сделать код более читабельным. Когда объект-генератор затем используется с sum()
функцией, мы получаем тот же результат. Только в этот момент выполняются расчеты.
events = [("learn", 5), ("learn", 10), ("relaxed", 20)] minutes_studied = 0 for event in events: if event[0] == "learn": minutes_studied += event[1] print(minutes_studied) # 15 # --> Refactor study_times = (event[1] for event in events if event[0] == "learn") minutes_studied = sum(study_times) print(minutes_studied) # 15
5) Больше используйте itertools!
Модуль itertools предоставляет функции, создающие итераторы для эффективного цикла. Давайте рассмотрим три из этих функций:
islice()
pairwise()
takewhile()
itertools.islice()
Он создает итератор, который возвращает выбранные элементы из итерируемого объекта.
lines = ["line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8", "line9", "line10"] for i, line in enumerate(lines): if i >= 5: break print(line) # --> Refactor from itertools import islice first_five_lines = islice(lines, 5) for line in first_five_lines: print(line) # line1 # line2 # line3 # line4 # line5
pairwise()
Возвращает последовательные перекрывающиеся пары, взятые из входного итерируемого объекта.
data = 'ABCDE' for i in range(len(data)-1): print(data[i], data[i+1]) # --> Refactor from itertools import pairwise for pair in pairwise('ABCDE'): print(pair[0], pair[1]) # A B # B C # C D # D E
takewhile()
Он создает итератор, который возвращает элементы из итерируемого объекта, если утверждение истино.
for item in [1, 2, 4, -1, 4, 1]: if item >= 0: print(item) else: break # --> Refactor from itertools import takewhile items = takewhile(lambda x: x >= 0, [1, 2, 4, -1, 4, 1]) for item in items: print(item) # 1 # 2 # 4
6) Используйте NumPy
Если скорость очень важна, вы можете использовать NumPy. Он предоставляет множество соответствующих функций для встроенных функций, таких как np.sum()
и np.arange()
т. д.
Функции NumPy обычно намного быстрее. Однако имейте в виду, что с такими функциями, как np.arange()
весь массив, выделяется в памяти и, таким образом, в результате занимает больше места, в то время как функции Python range()
не нужно выделять весь массив.
import numpy as np sum(range(10)) # --> Refactor np.sum(np.arange(10))