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

 



 

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии