Условие назначения в Python while Loop - PullRequest
25 голосов
/ 16 октября 2011

В C можно сделать

while( (i=a) != b ) { }

, но в Python, похоже, нельзя.

while (i = sys.stdin.read(1)) != "\n":

генерирует

    while (i = sys.stdin.read(1)) != "\n":
         ^
SyntaxError: invalid syntax

(^ должен быть на =)

Есть ли обходной путь?

Ответы [ 5 ]

22 голосов
/ 16 октября 2011

Использовать перерыв:

while True:
    i = sys.stdin.read(1)
    if i == "\n":
       break
    # etc...
9 голосов
/ 09 февраля 2012

Вы можете сделать это, используя встроенную функцию iter(), используя метод вызова с двумя аргументами:

import functools
for i in iter(fuctools.partial(sys.stdin.read, 1), '\n'):
    ...

Документация для этого:

iter(o[, sentinel])
...
Если задан второй аргумент sentinel , тогда o должен быть вызываемым объектом.Созданный в этом случае итератор будет вызывать o без аргументов для каждого вызова его метода next();если возвращаемое значение равно sentinel , * будет увеличено StopIteration, в противном случае будет возвращено значение.

Одно полезное применение второй формы iter() - читать строки файла, пока не будет достигнута определенная строка.В следующем примере файл читается до тех пор, пока метод readline() не возвратит пустую строку:

with open('mydata.txt') as fp:
    for line in iter(fp.readline, ''):
        process_line(line)
7 голосов
/ 13 апреля 2015

Версия без functools:

for i in iter(lambda: sys.stdin.read(1), '\n'):
3 голосов
/ 27 апреля 2019

Начиная с Python 3.8 и введением выражений присваивания (PEP 572) (оператор :=), теперь можно захватывать значение выражения (здесь sys.stdin.read(1)) как переменную по порядку использовать его в теле while:

while (i := sys.stdin.read(1)) != '\n':
  do_smthg(i)

Это:

  • Назначает sys.stdin.read(1) переменной i
  • Сравнение i с \n
  • Если условие подтверждено, вводится тело while, в котором можно использовать i
3 голосов
/ 16 октября 2011

Лично мне нравятся ответы imm и Marks с использованием break, но вы также можете сделать:

a = None
def set_a(x):
    global a
    a = x
    return a

while set_a(sys.stdin.read(1)) != '\n':
    print('yo')

, хотя я бы не рекомендовал это.

...