Цикли

while

Якби ми хотіли імітувати поведінку нашого традиційного for циклу в стилі C в Python, ми могли б використати whileцикл:

colors = ["red", "green", "blue", "purple"]
i = 0
while i < len(colors):
print(colors[i])
i += 1

Це передбачає ті самі 4 кроки, що й forцикли інших мов (зауважте, що ми встановлюємо, перевіряємо та збільшуємо i), але це не настільки компактно.

Цей метод циклу в Python дуже рідкісний.

діапазон довжини

Я часто бачу, як нові програмісти Python намагаються відтворити традиційні forцикли трохи більш креативно в Python:

colors = ["red", "green", "blue", "purple"]

for i in range(len(colors)):

print(colors[i])


Це спочатку створює діапазон, відповідний індексам у нашому списку ( 0 до len(colors) - 1). Ми можемо прокручувати цей діапазон, використовуючи вхідний цикл Python (насправді foreach ).

Це надає нам індекс кожного елемента у нашому colors списку, що так само, як forпрацюють петлі у стилі С. Для отримання фактичного кольору ми використовуємо colors[i].

for-in: звичайний спосіб

Як цикл while, так і метод діапазону значень покладаються на циклічний перегляд індексів. Але насправді нас не цікавлять індекси: ми використовуємо ці індекси лише з метою отримання елементів із нашого списку.

Оскільки насправді насправді не цікавлять індекси у нашому циклі, ми можемо використовувати набагато простіший метод циклу :

colors = ["red", "green", "blue", "purple"]
for color in colors:
print(color)

Отже, замість отримання індексів елементів та пошуку кожного елемента, ми можемо просто прокрутити наш список, використовуючи звичайний вхідний цикл.

Інші два методи, які ми обговорювали, іноді називають анти-шаблонами, оскільки це шаблони програмування, які широко вважаються унідіоматичними.

Що робити, якщо нам потрібні індекси?

Що робити, якщо нам насправді потрібні індекси? Наприклад, припустимо, ми друкуємо імена президентів разом з їх номерами (на основі індексів списків).

діапазон довжини

Ми могли б використовувати, range(len(our_list))а потім шукати індекс, як раніше:

presidents = ["Washington", "Adams", "Jefferson", "Madison", "Monroe", "Adams", "Jackson"]
for i in range(len(presidents)):
print("President {}: {}".format(i + 1, presidents[i]))

Але є більш ідіоматичний спосіб виконати це завдання: скористатися enumerate функцією.

перерахувати

Вбудована enumerate функція Python дозволяє нам перебирати список і отримувати як індекс, так і значення кожного елемента у списку:

presidents = ["Washington", "Adams", "Jefferson", "Madison", "Monroe", "Adams", "Jackson"]

for num, name in enumerate(presidents, start=1):

print("President {}: {}".format(num, name))

enumerateФункція дає нам ітератор , де кожен елемент є кортеж , який містить індекс елемента і вихідного значення елемента.

Ця функція призначена для вирішення завдання:

  1. Доступ до кожного елемента у списку (або до іншого ітеративного)

  2. Також отримуємо індекс кожного пункту доступу

Тому, коли нам потрібні індекси предметів під час циклу, нам слід подумати enumerate.

Що робити, якщо нам потрібно прокрутити кілька речей?

Часто, коли ми використовуємо індекси списків, це щось шукати в іншому списку.

перерахувати

Наприклад, тут ми переглядаємо два списки одночасно, використовуючи індекси для пошуку відповідних елементів:


colors = ["red", "green", "blue", "purple"]

ratios = [0.2, 0.3, 0.1, 0.4]

for i, color in enumerate(colors):

ratio = ratios[i]

print("{}% {}".format(ratio * 100, color))


Зверніть увагу, що індекс нам потрібен лише в цьому сценарії, оскільки ми використовуємо його для пошуку елементів за тим самим індексом у нашому другому списку. Насправді ми хочемо прокрутити два списки одночасно: індекси просто надають засоби для цього.

застібку-блискавку

Ми насправді не дбаємо про індекс, коли цикл тут. Наша справжня мета - прокрутити два списки одночасно. Ця потреба є досить поширеною, що для цього існує спеціальна вбудована функція.

zipФункція Python дозволяє нам циклічно переглядати кілька списків одночасно :

colors = ["red", "green", "blue", "purple"]
ratios = [0.2, 0.3, 0.1, 0.4]
for color, ratio in zip(colors, ratios):
print("{}% {}".format(ratio * 100, color))


zip функція приймає кілька списків і повертає ітератор , який забезпечує кортеж відповідних елементів кожен список , як ми перебираємо його.

Зверніть увагу, що zipпри різних розмірах списки зупиняться після того, як у найкоротшому списку закінчаться елементи. Можливо, вам захочеться заглянути в itertools.zip_longest, якщо вам потрібна інша поведінка. Також зверніть увагу, що zipв Python 2 повертає список, але zipв Python 3 повертає ледачий ітерабель. У Python 2 itertools.izipеквівалентно новішій zipфункції Python 3 .