I wrote a python program to print the ascii value of up to every 3 numbers in a string or "ERROR"
if the length is not divisible by three. I was golf the code when I ran into a SyntaxError
.
Code:
c=input() p=len(c) c=[int(c[i:i+3])for i in range(0,len(c),3)] print("ERROR"if p%3else*map(chr,c),sep='')#SyntaxError here
But this works:
c=input() p=len(c) c=[int(c[i:i+3])for i in range(0,len(c),3)] print(*map(chr,c),sep='')
Putting a space before the *
or after the 3
doesn’t work. I could just use ''.join
but it’s one character longer. My question is why can’t I use a starred expression in a ternary operator?
Advertisement
Answer
Because the *
has to apply to the whole expression that produces the set of arguments, not a part of it, and not conditionally. Internally, CPython uses different bytecodes for calling with unpacking vs. normal calls, so your conditional would require it to change the byte code to call print
based on the arguments to print
, essentially rewriting what you wrote into pseudocode like:
if p % 3: call(print, "ERROR", sep='') else: call_varargs(print, *map(chr, c), sep='')
which is beyond the compiler’s capability.
If you wanted to make this work, you could do the following:
print(*(("ERROR",) if p%3 else map(chr,c)), sep='')
which ensures the whole ternary evaluates to an unpackable sequence and unpacks whatever survives unconditionally, avoiding the confusion.