Skip to content
Advertisement

Starred expression in ternary operator python

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.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement