Assignment Condition in Python While Loop
Question:
In C, one can do
while( (i=a) != b ) { }
but in Python, it appears, one cannot.
while (i = sys.stdin.read(1)) != "n":
generates
while (i = sys.stdin.read(1)) != "n":
^
SyntaxError: invalid syntax
(the ^
should be on the =
)
Is there a workaround?
Answers:
Use break:
while True:
i = sys.stdin.read(1)
if i == "n":
break
# etc...
Personally I like imm’s and Marks answers using break
, but you could also do:
a = None
def set_a(x):
global a
a = x
return a
while set_a(sys.stdin.read(1)) != 'n':
print('yo')
though I wouldn’t recommend it.
You can accomplish this using the built-in function iter()
using the two-argument call method:
import functools
for i in iter(fuctools.partial(sys.stdin.read, 1), 'n'):
...
Documentation for this:
iter(o[, sentinel])
…
If the second argument, sentinel, is given, then o must be a callable object. The iterator created in this case will call o with no arguments for each call to its next()
method; if the value returned is equal to sentinel, StopIteration
will be raised, otherwise the value will be returned.
One useful application of the second form of iter()
is to read lines of a file until a certain line is reached. The following example reads a file until the readline()
method returns an empty string:
with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
A version without functools
:
for i in iter(lambda: sys.stdin.read(1), 'n'):
Starting Python 3.8
, and the introduction of assignment expressions (PEP 572) (:=
operator), it’s now possible to capture an expression value (here sys.stdin.read(1)
) as a variable in order to use it within the body of while
:
while (i := sys.stdin.read(1)) != 'n':
do_smthg(i)
This:
- Assigns
sys.stdin.read(1)
to a variable i
- Compares
i
to n
- If the condition is validated, enters the
while
body in which i
can be used
In C, one can do
while( (i=a) != b ) { }
but in Python, it appears, one cannot.
while (i = sys.stdin.read(1)) != "n":
generates
while (i = sys.stdin.read(1)) != "n":
^
SyntaxError: invalid syntax
(the ^
should be on the =
)
Is there a workaround?
Use break:
while True:
i = sys.stdin.read(1)
if i == "n":
break
# etc...
Personally I like imm’s and Marks answers using break
, but you could also do:
a = None
def set_a(x):
global a
a = x
return a
while set_a(sys.stdin.read(1)) != 'n':
print('yo')
though I wouldn’t recommend it.
You can accomplish this using the built-in function iter()
using the two-argument call method:
import functools
for i in iter(fuctools.partial(sys.stdin.read, 1), 'n'):
...
Documentation for this:
iter(o[, sentinel])
…
If the second argument, sentinel, is given, then o must be a callable object. The iterator created in this case will call o with no arguments for each call to itsnext()
method; if the value returned is equal to sentinel,StopIteration
will be raised, otherwise the value will be returned.One useful application of the second form of
iter()
is to read lines of a file until a certain line is reached. The following example reads a file until thereadline()
method returns an empty string:
with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
A version without functools
:
for i in iter(lambda: sys.stdin.read(1), 'n'):
Starting Python 3.8
, and the introduction of assignment expressions (PEP 572) (:=
operator), it’s now possible to capture an expression value (here sys.stdin.read(1)
) as a variable in order to use it within the body of while
:
while (i := sys.stdin.read(1)) != 'n':
do_smthg(i)
This:
- Assigns
sys.stdin.read(1)
to a variablei
- Compares
i
ton
- If the condition is validated, enters the
while
body in whichi
can be used