В этом уроке мы рассмотрим 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))