Подтвердить что ты не робот

Зачем избегать циклов?

Я изучаю Python в течение 2 недель в качестве вводного языка. Я попал в точку в Zed "Learn Python the Hard Way", где он предлагает:

Используйте цикл while только для цикла навсегда, и это означает, что, вероятно, никогда. Это относится только к     на Python, другие языки разные.

Я искал все это, ссылаясь на все, что могу, но я не могу найти никакой причины в мире, почему это будет соглашение в Python. Что отличает его?

Когда я отказался от программирования 10 лет назад, я работал в VB, и мне регулярно говорили, чтобы избавиться от моих циклов For и использовать While Loops вместо этого. Я был взломан (как и сегодня, хотя тогда я написал много кода), поэтому я просто сделал то, что мне сказали, не подвергая сомнению его. Ну, теперь я спрашиваю об этом. Это проблема скорости? Это просто избежать бесконечных бесконечных?

4b9b3361

Ответ 1

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

Например:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while n != 0:
        m, n = n, m % n
    return m

Вы можете изменить это на:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while True:
        if n == 0:
            return m
        m, n = n, m % n

но действительно ли это улучшение? Думаю, что нет.

Ответ 2

Это потому, что в типичной ситуации, когда вы хотите итерации, python может справиться с этим для вас. Например:

>>> mylist = [1,2,3,4,5,6,7]
>>> for item in mylist:
...     print item
... 
1
2
3
4
5
6
7

Аналогичный пример со словарем:

>>> mydict = {1:'a', 2:'b', 3:'c', 4:'d'}
>>> for key in mydict:
...     print "%d->%s" % (key, mydict[key])
... 
1->a
2->b
3->c
4->d

Использование цикла while просто не требуется во множестве общих сценариев использования (и не является "pythonic" ).


Здесь одно сравнение из списка рассылки, что я, однако, тоже была хорошей иллюстрацией:

> 2. Я знаю, что Perl отличается, но просто нет эквивалента while > ($line = <A_FILE>) { }?

Python для цикла имеет встроенный знания об "истребимых" объектах, и включает файлы. Попробуйте использовать:

for line in file:
    ...

который должен сделать трюк.

Ответ 3

Python следует философии

Должен быть один - и предпочтительно только один - простой способ сделать это.

(подробнее см. https://www.python.org/dev/peps/pep-0020/).

И в большинстве случаев есть лучший способ делать итерации в Python, чем использовать цикл while.

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

Пример: https://www.python.org/doc/essays/list2str

Используйте встроенные операции. Подразумеваемая петля на карте() быстрее, чем явный для цикла; цикл while с явный счетчик циклов равен медленнее.

У меня нет объяснений, почему вам сказали использовать while, а не для циклов в VB, - я думаю, что он обычно не ведет ни к более читабельному, ни к более быстрому коду.

Ответ 4

Цикл while - это инструмент, не более того. Чтобы использовать его или не использовать, речь идет о том, является ли он правильным инструментом для работы, не более того. Вы правы, спрашиваете совета, это глупо.

Говорят, что в python есть конструкции, которые устраняют необходимость while while while. Например, перечисления в списках делают то, что обычно можно делать с временем или для цикла.

Используйте правильный инструмент для задания, не пытайтесь запоминать и придерживаться кучи правил. Цель состоит в том, чтобы написать код, который а) работает, и б) ясно.

Ответ 5

Это не проблема скорости, и это то, что есть, предложение.

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

Ответ 6

Общая проблема с циклами while заключается в том, что ее легко упускать из виду или каким-то образом пропускать оператор, в котором переменная цикла увеличивается. Даже C-цикл может иметь эту проблему - вы можете написать for(int x=0; x<10;), хотя это маловероятно. Но цикл Python for не имеет такой проблемы, поскольку он заботится о продвижении итератора для вас. С другой стороны, цикл while заставляет вас внедрять инкремент без сбоев.

s = "ABCDEF"
i = 0
while (i < len(s)):
    if s[i] in "AEIOU":
        print s[i], 'is a vowel'
        i += 1

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

Ответ 7

>>> counter = 0
>>> while counter < 5:
       print counter
       counter += 1         
0
1
2
3
4

>>> for x in range(5):
       print x          
0
1
2
3
4

Смотрите сами, какой из них вы предпочитаете?;)

Когда легче понять и легче читать код работает, то есть путь Python-ic.

Ответ 8

Позвольте мне поделиться с вами секретом: Девять раз из десяти с python, ответ просто "использует здравый смысл". Это не ужасно сложный язык (помимо некоторых заметных ошибок). В этом случае я бы счел излишним избыточное правило Зеда, потому что почти всегда здравый смысл знать, какой цикл использовать.

Тем не менее, если я столкнулся с ситуацией, требующей итерации, и у меня есть выбор, я предпочитаю следующее (от максимального до наименьшего предпочтения):

  • Список/генератор/набор/определение dict
  • Для цикла
  • Пока цикл
  • Рекурсия

Понятия просты, но удивительно, сколько раз вы можете сделать цикл for в одном, если вы вложите в него мысли. Но, как правило, я бы сказал, что около 90% всей итерации я буду делать с пониманием списка или циклом for.

Ответ 9

Также есть список понятий, например:
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]

Ответ 10

Это идиома, которую я часто использую:

done = False
while not done:
    done = DoSomeStuffAndReturnTrueIfAllDone()
    # wait a while before polling again for more work
    time.sleep(5)

Я мог бы вытащить это в генератор, конечно, но я не вижу в этом победы. Существуют ли другие питонические способы сделать это?

Отредактировано, чтобы уточнить, что я периодически опроса для работы.

Ответ 11

Цикл for лучше всего подходит для цикла через коллекцию. Я в основном думаю, что цикл for является "определенным циклом". Использование цикла for для коллекции предотвращает ошибки, возникающие при попытке использовать индексы, которые находятся за пределами границ, или от случайного использования отрицательных индексов. Если вы не находитесь в особой ситуации, используйте цикл for для перемещения коллекции.

Цикл while наиболее полезен для ситуаций, когда вам, возможно, придется повторять действие неограниченное количество раз. Это "неопределенная петля". Пример, показанный выше для вычисления gcd, является ярким примером того, где использовать цикл while. Вы должны помнить, что предикат в то время должен измениться, или вы можете застрять в бесконечном цикле.

Если это вообще возможно, избегайте использования break для выхода из цикла.

Ответ 12

Я думаю, что использование бесконечного цикла концептуально неверно, потому что по его определению алгоритм состоит из конечного числа команд (wikipedia):

В математике, информатике и смежных предметах алгоритм [...] является эффективным методом решения задачи, выраженной как конечная последовательность шагов.

На мой взгляд, лучше найти другое решение, чем бесконечный цикл, когда это возможно, и это относится ко всем языкам программирования, прошедшим, настоящим и будущим.

Ответ 13

Зачем избегать циклов? В целях обучения. Я цитирую из книги:

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

Дело в том, что некоторые из этих правил глупые все время, в реальной жизни. Избегайте, пока петель один. Его правило для циклов - это то, что вы используете их, когда есть список (или кортеж или генератор) элементов для перебора или фиксированного количества итераций. Это верно. Когда этого не происходит, и вместо этого у вас есть определенное состояние или условие, которое вы хотите достичь, вы используете while while. Только использование их, когда у вас есть бесконечный цикл (например, обработчики событий), является глупым правилом. Но новички часто используют их слишком часто, возможно, поэтому у него есть правило там.