views:

431

answers:

2

Python is doing string multiplication where I would expect it to do numeric multiplication, and I don't know why.

>>> print('%d' % 2 * 4)
2222
>>> print('%d' % (2 * 4))
8

Even forcing the type to integer does nothing. (I realize this is redundant, but it's an idiot-check for me:

 >>> print('%d' % int(2) * int(4))
 2222

Obviously I solved my problem (adding the parenthesis does it) but what's going on here? If this is just a quirk I have to remember, that's fine, but I'd rather understand the logic behind this.

+1  A: 

Ah, I think I figured it out. Just after I posted the message, of course. It's an order-of-operations thing. The string formatting is being calculated, and the resulting string is being string multiplied against the last operand.

When I type:

>>> print '%d' % 2 * 4
2222

It turns out to be as if I had specified the precedence this way:

>>> print ('%d' % 2) * 4
2222
Schof
+7  A: 

You are experiencing operator precedence.

In python % has the same precedence as * so they group left to right.

So,

print('%d' % 2 * 4)

is the same as,

print( ('%d' % 2) * 4)

Here is the python operator precedence table.

Since it is difficult to remember operator precedence rules, and the rules can be subtle, it is often best to simply use explicit parenthesis when chaining multiple operators in an expression.

Karl Voigtland
Not as classy to accept my own answer, so Karl gets the check for most succinct and correct answer.
Schof
"so they group left to right" specifically, that's because the "*", "%" group of operators have left-associativity. "**" groups right to left
newacct
"You are experiencing operator precedence." Is that something to see a doctor for?
balpha