У меня есть следующий код, использующий цикл for:
total = 0
for num in range(101):
total = total + num
print(total)
Теперь тот же результат с использованием цикла while:
num = 0
total = 0
while num <= 99:
num = num + 1
total = total + num
print(total)
Почему мне не нужно определять num в первом случае, но я должен определить его во втором? Они оба не переменные?
В python в большинстве случаев нет необходимости определять/объявлять переменные.
Правило состоит в том, что если вы записываете (назначаете) переменную, то эта переменная является локальной переменной функции; если вы только читаете его вместо этого, то это глобальный.
Переменные, назначенные на верхнем уровне (вне любой функции), являются глобальными... например:
x = 12 # this is an assignment, and because we're outside functions x
# is deduced to be a global
def foo():
print(x) # we only "read" x, thus we're talking of the global
def bar():
x = 3 # this is an assignment inside a function, so x is local
print(x) # will print 3, not touching the global
def baz():
x += 3 # this will generate an error: we're writing so it's a
# local, but no value has been ever assigned to it so it
# has "no value" and we cannot "increment" it
def baz2():
global x # this is a declaration, even if we write in the code
# x refers to the global
x += 3 # Now fine... will increment the global
Оператор for
— это просто цикл, который записывает в переменную: если объявление отсутствует, переменная будет считаться локальной; если есть объявление global
или nonlocal
, то используемая переменная будет иметь соответствующую область видимости (nonlocal
используется для записи в локальную переменную объемлющей функции из кода во вложенной функции: в Python это используется не очень часто).
Ну, for
— это специальный оператор, который автоматически определяет переменную для вас. Было бы излишним требовать от вас объявления переменной заранее.
while
— это конструкция цикла общего назначения. Условие для оператора while
даже не должно включать переменную; Например
while True:
или
while my_function() > 0:
Если вы используете другие языки программирования, такие как C
, C++
или Java
, не путайте for in
с циклом Python.
В python цикл for in
выбирает один элемент из списка элементов и что-то делает с помощью выбранного элемента.
For Loop повторяет каждый элемент из списка до заданного диапазона. Поэтому нет необходимости в какой-либо переменной для проверки условия.
Пока Цикл повторяется до тех пор, пока заданное условие не станет истинным. Здесь нам нужна некоторая переменная или значение для проверки условия, поэтому перед циклом используется переменная num.
Циклы Python for
присваивают переменную и позволяют вам ее использовать. Мы можем преобразовать цикл for
в цикл while
, чтобы понять, как на самом деле Python это делает (подсказка: он использует итерации!):
iterator = iter(iterable) # fresh new iterator object
done = False
while not done:
try:
item = next(iterator)
except StopIteration:
done = True
else:
# inside code of a for loop, we can use `item` here
pass
«Для ясности и корректности в теле блока try должны быть только операторы, которые могут генерировать ожидаемые исключения». Из книги «Свободный Python» Лучано Рамальо. @gmds
Я хотел бы подойти к этому вопросу с несколько иной точки зрения.
Если мы посмотрим на официальная спецификация грамматики Python, то увидим, что (приблизительно) оператор while
принимает test
, а оператор for
принимает exprlist
и testlist
.
Таким образом, концептуально мы можем понять, что оператору while
нужна одна вещь: выражение, которое он может многократно вычислять.
С другой стороны, оператору for
требуется два: набор выражений для оценки, а также ряд имен для привязки результатов этих оценок.
Имея это в виду, имеет смысл, что оператор while
не будет автоматически создавать временную переменную, поскольку он также может принимать литералы. И наоборот, оператор for
должен связывается с некоторыми именами.
(Строго говоря, с точки зрения грамматики Python допустимо помещать литерал там, где вы ожидаете имя в выражении for
, но контекстуально это не имеет смысла, поэтому язык запрещает это.)
Потому что цикл
for
управляет параметр значениямиnum
, а циклwhile
только читает значениямиnum
. Если бы он их тоже устанавливал, то, возможно, не требовалось бы предварительно определятьnum
.