Python Присвоить значение переменной во время условия while, в то время как Loop
Простой вопрос о синтаксисе Python. Я хочу назначить значение из функции переменной во время условия цикла while. Когда значение, возвращаемое функцией, является ложным, цикл должен прерываться. Я знаю, как это сделать в PHP.
while (($data = fgetcsv($fh, 1000, ",")) !== FALSE)
Однако, когда я пытаюсь использовать аналогичный синтаксис в Python, я получаю синтаксическую ошибку.
Ответы
Ответ 1
Вы не можете использовать присваивание в выражении. Назначение само по себе является оператором, и вы не можете комбинировать операторы Python.
Это явный выбор, сделанный дизайнерами языка; слишком легко случайно использовать один =
и назначить, где вы хотели использовать два ==
и проверить на равенство.
Переместите присваивание в цикл или присвойте его перед циклом и назначьте новые значения в самом цикле.
В вашем конкретном примере модуль Python csv
предоставляет вам высокоуровневый API, и вместо этого вы будете переходить к csv.reader()
:
with open(csvfilename, 'rb') as csvfh:
reader = csv.reader(csvfh)
for row in reader:
Мне редко, если вообще нужно, нужно назначать в конструкции цикла. Обычно есть (намного) лучший способ решения проблемы.
Тем не менее, начиная с Python 3.8 язык будет фактически иметь выражения присваивания, используя :=
в качестве оператора присваивания. Смотрите PEP 572. Выражения присваивания действительно полезны при понимании списков, например, когда вам нужно включить возвращаемое значение метода в создаваемый вами список и иметь возможность использовать это значение в тесте.
Теперь вам нужно использовать выражение генератора:
absolute = (os.path.abspath(p) for p in files)
filtered = [abs for abs in absolute if included(abs)]
но с помощью выражений присваивания вы можете встроить вызов os.path.abspath()
:
filtered = [abs for p in files if included(abs := os.path.abspath(p))]
Ответ 2
Вы не можете сделать это в Python, без присваивания в выражениях. По крайней мере, это означает, что вы случайно не будете набирать == вместо = или наоборот и будете работать.
Традиционный стиль Python должен использовать только True и break:
while True:
data = fgetcsv(fh, 1000, ",")
if not data:
break
# Use data here
Но теперь я бы поставил это в генераторе:
def data_parts(fh):
while True:
data = fgetcsv(fh, 1000, ",")
if not data:
break
yield data
так что в коде, который использует файл, уродство скрывается:
for data in data_parts(fh):
# Use data here
Конечно, если это действительно CSV-чтение, которое вы делаете, используйте модуль csv.
Ответ 3
Я написал небольшой модуль Python, который я называю let
, который позволяет выполнять присвоение переменной в любом месте, где разрешена функция.
Установите его следующим образом:
pip install let
Я верю, что следующее выполнит то, что вы ищете:
from let import let
while let(data = fgetcsv(fh, 1000, ',')):
# Do whatever you'd like with data here
Однако... Дункан комментирует исходный вопрос, говорящий, что использовать iter
интересно. Я не знал об этой функции, пока не поднял ее, и теперь я считаю, что это может быть лучшим решением, чем мое. Он дискуссионный - iter
требует, чтобы контролер был явно предоставлен, в то время как мой не заботится и просто ждет fgetcsv
, чтобы вернуть любое значение False
y.
Ответ 4
Python 3.8 pep-0572 теперь решает эту проблему, используя новую запись :=
. Посмотрите :)
Например:
while chunk := file.read(8192):
process(chunk)