Consider the following code snippet. It flags a syntax error at the break statement.
digits = list(str(102))
dummy = list(str(102/2))
for j in digits:
dummy.remove(j) if j in dummy else break
How do I fix this?(I want to still use the ternary operator)
2 Answers 2
Edit:
(see my conversation with Stefan Pochmann in the comments)
Ternary operator is not for only statement, but rather for assignment or for expression (and break
is an only statement):
a = 5 if cond else 3 #OK
do() if cond else dont() #also OK
do() if cond else break #not OK
use normal if-else
statement to do statements:
if cond:
do()
else:
break
-
2Your examples aren't quite the same, as they are valid syntaxjonrsharpe– jonrsharpe05/13/2016 15:55:55Commented May 13, 2016 at 15:55
-
3@TheChetan: no, there isn't. Python focuses on readability, not conciseness.Martijn Pieters– Martijn Pieters05/13/2016 15:56:07Commented May 13, 2016 at 15:56
-
1@TheChetan hmm... depends on the case, you could in fact make for loop and store the functions in
list
first for instanceIan– Ian05/13/2016 15:56:14Commented May 13, 2016 at 15:56 -
1@sparkandshine ah I get it... that is because
exit
is a function. If you use tool likePyCharm
you can see that.. it is like function returning nothingIan– Ian05/13/2016 16:11:48Commented May 13, 2016 at 16:11 -
1@Ian Ah, ok. The problem is that they're only statements, not expressions, and you need an expression there.Stefan Pochmann– Stefan Pochmann05/13/2016 16:18:46Commented May 13, 2016 at 16:18
You cannot use break in Your loop logic can be re written using itertools.takewhile if you want a more succinct solution
digits = list(str(102))
dummy = list(str(102/2))
from itertools import takewhile
for d in takewhile(dummy.__contains__, digits):
dummy.remove(d)
You can also remove the need for the else using a for loop by reversing your logic, check if j is not in dummy breaking when that is True:
for j in digits:
if j not in dummy:
break
dummy.remove(j)
Also if you want to remove all occurrences of any of the initial elements from digits that are in dummy, remove won't do that for any repeating elements but using a list comp after creating a set of elements to remove will:
digits = str(102)
dummy = list(str(102/2))
st = set(takewhile(dummy.__contains__, digits))
dummy[:] = [d for d in dummy if d not in st]
print(dummy)
You can also iterate over a string so no need to call list on digits unless you plan on doing some list operations with it after.
-
2Ugh, it's awkward to avoid the dunder method here; you can use
functools.partial
andoperator.contains
, e.g.in_dummy = partial(contains, dummy)
. This seems like a lot of work to avoid the underscore method though, and no real benefits. A lambda could be used alternatively, e.g.lambda e: e in dummy
.Jared Goguen– Jared Goguen05/13/2016 16:42:26Commented May 13, 2016 at 16:42 -
@JaredGoguen, yep, I don't mind using
__contains__
in a case like this, definitely better than a lambda, might be interesting to time the comparisons.Padraic Cunningham– Padraic Cunningham05/13/2016 16:49:54Commented May 13, 2016 at 16:49
break
is a statement, and as such it can't be used inside a ternary. Sorry.