Когда использовать «while» или «for» в Python - PullRequest
30 голосов
/ 28 мая 2009

Я нахожу проблемы, когда мне нужно использовать цикл while или цикл for в Python. Похоже, что люди предпочитают использовать for цикл (меньше строк кода?) . Есть ли какая-то конкретная ситуация, которую я должен использовать один или другой? Это вопрос личных предпочтений? Коды, которые я прочитал до сих пор, заставили меня думать, что между ними есть большие различия.

Ответы [ 6 ]

60 голосов
/ 28 мая 2009

Да, между while и for есть огромная разница.

Оператор для выполняет итерацию по коллекции, или итерируемому объекту, или функции генератора.

Оператор while просто зацикливается, пока условие не станет False.

Это не предпочтение. Вопрос в том, каковы ваши структуры данных.

Часто мы представляем значения, которые мы хотим обработать, как range (фактический список) или xrange (который генерирует значения). Это дает нам структуру данных, специально разработанную для оператора for .

Однако, как правило, у нас есть готовая коллекция: набор, кортеж, список, карта или даже строка уже итеративная коллекция, поэтому мы просто используем цикл для .

В некоторых случаях нам может потребоваться выполнить некоторую обработку функционального программирования, и в этом случае мы можем применить это преобразование как часть итерации. Функции sorted и enumerate применяют к итерируемому преобразование, которое естественным образом согласуется с оператором for .

Если у вас нет аккуратной структуры данных для перебора, или у вас нет функции генератора, которая управляет вашей обработкой, вы должны использовать , а .

20 голосов
/ 28 мая 2009

while полезно в сценариях, где условие разрыва логически не зависит от какой-либо последовательности. Например, рассмотрим непредсказуемые взаимодействия:

 while user_is_sleeping():
     wait()

Конечно, вы могли бы написать соответствующий итератор для инкапсуляции этого действия и сделать его доступным через for - но как это послужило бы удобочитаемости? 100

Во всех других случаях в Python используйте for (или соответствующую функцию более высокого порядка, которая инкапсулирует цикл).

¹ при условии, что функция user_is_sleeping возвращает False, когда ложь, пример кода можно переписать в виде следующего цикла for:

for _ in iter(user_is_sleeping, False):
    wait()
13 голосов
/ 28 мая 2009

for является более питонным выбором для итерации списка, поскольку его проще и легче читать.

Например, это:

for i in range(11):
    print i

намного проще и легче для чтения, чем это:

i = 0
while i <= 10:
    print i
    i = i + 1
4 голосов
/ 28 мая 2009

Прежде всего, есть различия между циклом for в python и в других языках. Хотя в python он выполняет итерацию по списку значений (например, для значения в [4,3,2,7]), в большинстве других языков (C / C ++, Java, PHP и т. Д.) Он действует как цикл while, но проще читать.

Циклы for обычно используются, когда известно число итераций (например, длина массива), а циклы используются, когда вы не знаете, сколько времени это займет (например, пузырьковая сортировка ). алгоритм, который зацикливается, пока значения не отсортированы)

3 голосов
/ 28 мая 2009

Рассмотрим обработку итераций. Вы можете сделать это с помощью for loop:

for i in mylist:
   print i

Или вы можете сделать это с помощью while loop:

it = mylist.__iter__()
while True:
   try:
      print it.next()
   except StopIteration:
      break

Оба этих блока кода в основном делают одно и то же, в основном одинаково. Но цикл for скрывает создание итератора и обработку исключения StopIteration, поэтому вам не нужно разбираться с ними самостоятельно.

Единственный раз, когда я могу подумать, что вы использовали бы цикл while для обработки итерируемого, это если бы вам по какой-то причине был необходим прямой доступ к итератору, например при некоторых обстоятельствах вам нужно было пропускать элементы списка.

2 голосов
/ 28 мая 2009

Для циклов обычно проясняют, что делает итерация. Вы не всегда можете использовать их напрямую, но в большинстве случаев логика итерации с циклом while может быть заключена в функцию генератора. Например:

def path_to_root(node):
    while node is not None:
        yield node
        node = node.parent

for parent in path_to_root(node):
    ...

Вместо

parent = node
while parent is not None:
    ...
    parent = parent.parent
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...