I want to know why does the following happen.
The code below evaluates right side 1**3 first then 2**1
2**1**3 has the value of 2
However, for the below code left side 7//3 is evaluated first then 2*3. Finally 1+6-1=6.
1+7//3*3-1 has the value of 6
Take a look at the documentation of operator precedence. Although multiplication * and floor division // have the same precedence, you should take note of this part:
Operators in the same box group left to right (except for exponentiation, which groups from right to left).
For the convention of 213 being evaluated right-associative, see cross-site dupe on the math stackexchange site: What is the order when doing xyz and why?
The TL;DR is this: since the left-associative version (xy)z would just equal xy*z, it's not useful to have another (worse) notation for the same thing, so exponentiation should be right associative.
Almost all operators in Python (that share the same precedence) have left-to-right associativity. For example:
1 / 2 / 3 ≡ (1 / 2) / 3
One exception is the exponent operator which is right-to-left associativity:
2 ** 3 ** 4 ≡ 2 ** (3 ** 4)
That's just the way the language is defined, matching mathematical notation where abc ≡ a(bc).
If it were (ab)c, that would just be abc.
Per Operator Precedence, the operator is right associative: a**b**c**d == a**(b**(c**d)).
So, if you do this:
a,b,c,d = 2,3,5,7
a**b**c**d == a**(b**(c**d))
you should get true after a looooong time.
The Exponent operator in python has a Right to Left precedence. That is out of all the occurrences in an expression the calculation will be done from Rightmost to Leftmost. The exponent operator is an exception among all the other operators as most of them follow a Left to Right associativity rule.
2**1**3 = 2
The expression
1+7//3*3-1
It is a simple case of Left to Right associativity. As // and * operator share the same precedence, Associativity(one is the Left) is taken into account.
This is just how math typically works
213
This is the same as the first expression you used. To evaluate this with math, you'd work your way down, so 13=1 and then 21 which equals 2.
You can make sense of this just by thinking about the classic PEMDAS (or Please Excuse My Dear Aunt Sally) order of operations from mathematics. In your first one, 2**1**3 is equivalent to , which is really read as . Looking at it this way, you see that you do parenthesis (P) first (the 1**3).
In the second one, 1+7//3*3-1 == 6 you have to note that the MD and AS of PEMDAS are actually done in order of whichever comes first reading from left-to-right. It's simply a fault of language that we have to write one letter before another (that is, we could write this as PEDMAS and it still be correct if we treat the D and M appropriately).
All that to say, Python is treating the math exactly the same way as we should even if this were written with pen and paper.
Related
I've been programming in Python for years but something extremely trivial has surprised me:
>>> -1 ** 2
-1
Of course, squaring any negative real number should produce a positive result. Probably Python's math is not completely broken. Let's look at how it parsed this expression:
>>> ast.dump(ast.parse('-1 ** 2').body[0])
Expr(
value=UnaryOp(
op=USub(),
operand=BinOp(
left=Num(n=1),
op=Pow(),
right=Num(n=2)
)
)
)
Ok, so it is treating it as if I had written -(1 ** 2). But why is the - prefix to 1 being treated as a separate unary subtraction operator, instead of the sign of the constant?
Note that the expression -1 is not parsed as the unary subtraction of the constant 1, but just the constant -1:
>>> ast.dump(ast.parse('-1').body[0])
Expr(
value=Num(n=-1)
)
The same goes for -1 * 2, even though it is syntactically nearly identical to the first expression.
>>> ast.dump(ast.parse('-1 * 2').body[0])
Expr(
value=BinOp(
left=Num(n=-1),
op=Mult(),
right=Num(n=2)
)
)
This behavior turns out to be common to many languages including perl, PHP, and Ruby.
It behaves just like the docs explain here:
2.4.4. Numeric literals
[...] Note that numeric literals do not include a sign; a phrase like -1 is actually an expression composed of the unary operator - and the literal 1.
and here:
6.5. The power operator
The power operator binds more tightly than unary operators on its
left; [...]
See also the precedence table from this part. Here is the relevant part from that table:
Operator | Description
-------------|---------------------------------
* | Multiplication, ...
+x, -x, ~x | Positive, negative, bitwise NOT
** | Exponentiation
This explains why the parse tree is different between the ** and * examples.
I am reading an Intro to Python textbook and came across this line:
Operators on the same row have equal precedence and are applied left to right, except for exponentiation, which is applied right to left.
I understand most of this, but I do not understand why they say exponentiation is applied right to left. They do not provide any examples either. Also, am I allowed to ask general questions like this, or are only problem solving questions preferred?
The ** operator follows normal mathematical conventions; it is right-associative:
In the usual computer science jargon, exponentiation in mathematics is right-associative, which means that xyz should be read as x(yz), not (xy)z. In expositions of the BODMAS rules that are careful enough to address this question, the rule is to evaluate the top exponent first.
and from Wikipedia on the Order of Operations:
If exponentiation is indicated by stacked symbols, the usual rule is to work from the top down, because exponention is right-associative in mathematics.
So 2 ** 3 ** 4 is calculated as 2 ** (3 ** 4) (== 2417851639229258349412352) not (2 ** 3) ** 4 (== 4096).
This is pretty universal across programming languages; it is called right-associativity, although there are exceptions, with Excel and MATLAB being the most notable.
from http://docs.python.org/reference/expressions.html
Operators in the same box group left to right (except for comparisons, including tests, which all have the same precedence and chain from left to right — see section Comparisons — and exponentiation, which groups from right to left).
>>> 2 ** 2 ** 2
16
>>> 2 ** 2 ** 2 ** 2
65536
>>> (2 ** 2 ** 2) ** 2
256
For the middle case 2 ** 2 ** 2 ** 2, this are the intermediate steps -
broken down to 2 ** (2 ** (2 ** 2))
2 ** (2 ** (4)) # progressing right to left
2 ** (16) # this is 2 to the power 16
which finally evals to 65536
Hope that helps!
This explanation seems quite clear to me. Let me show you an example that might enlighten this :
print 2 ** 2 ** 3 # prints 256
If you would read this from left to right, you would first do 2 ** 2, which would result in 4, and then 4 ** 3, which would give us 64.
It seems we have a wrong answer. :)
However, from right to left...
You would first do 2 ** 3, which would be 8, and then, 2 ** 8, giving us 256 !
I hope I was able to enlighten this point for you. :)
EDIT : Martijn Pieters answered more accurately to your question, sorry. I forgot to say it was mathematical conventions.
Power operator, exponentiation, is handled differently across applications and languages.
If it has LEFT associativity then 2^3^4 = (2^3)^4 = 4096.
If it has RIGHT associativity then 2^3^4 = 2^(3^4) = 2417851639229260000000000.
In Excel, Matlab, Apple Numbers and more others exponentiation has LEFT associativity.
In Python, Ruby, Google Sheets, ... - RIGHT associativity.
Here is a vast list of how different languages and apps handle exponentiation: Exponentiation Associativity and Standard Math Notation
Let's take a look at the simplest arithmetic example in the pyparsing doc, here.
More specifically, I'm looking at the "+" operation that is defined as left associative and the first example test where we're parsing "9 + 2 + 3".
The outcome of the parsing I would have expected would be ((9+2)+3), that is, first compute the infix binary operator on 9 and 2 and then compute the infix binary operator on the result and 3. What I get however is (9+2+3), all on the same level, which is really not all that helpful, after all I have now to decide the order of evaluation myself and yet it was defined to be left associative. Why am I forced to parenthesize myself? What am I missing?
Thanks & Regards
Examples of slicing in documentation only show integer literals and variables used as indices, not more complex expressions (e.g. myarray[x/3+2:x/2+3:2]). PEP-8 also doesn't cover this case. What is the usual usage of whitespace here: myarray[x/3+2:x/2+3:2], myarray[x/3+2 : x/2+3 : 2], or myarray[x/3+2: x/2+3: 2] (there don't seem to be other reasonable options)?
I have never seen spaces used in slicing operations, so would err on the side of avoiding them. Then again, unless it's performance critical I'd be inclined to move the expressions outside of the slicing operation altogether. After all, your goal is readability:
lower = x / 3 + 2
upper = x / 2 + 3
myarray[lower:upper:2]
I believe the most relevant extract of PEP8 on this subject is:
The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code.
In this case, my personal choice would probably be either Steve Mayne's answer, or perhaps:
myarray[slice(x / 3 + 2, x / 2 + 3, 2)]
Rule 1. Pet Peeves
However, in a slice the colon acts like a binary operator, and should
have equal amounts on either side (treating it as the operator with
the lowest priority). In an extended slice, both colons must have the
same amount of spacing applied. Exception: when a slice parameter is
omitted, the space is omitted:
Rule 2. Other Recommendations
If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator:
The following fails rule 2.
myarray[x/3+2:x/2+3:2]
myarray[x/3+2:x/2+3:2]
myarray[x/3+2 : x/2+3 : 2]
myarray[x/3+2: x/2+3: 2]
So the answer is,
myarray[x/3 + 2 : x/2 + 3 : 2]
Black Playground link Bug
What is the difference between the following statements?
Statement 1:
var=2**2*3
Statement 2:
var2=2*2*3
I see no difference.
This raises the following question.
Why is Statement 1 used if we can use Statement 2?
Try:
2**3*2
and
2*3*2
to see the difference.
** is the operator for "power of". In your particular operation, 2 to the power of 2 yields the same as 2 times 2.
Double stars (**) are exponentiation. So "2 times 2" and "2 to the power 2" are the same. Change the numbers and you'll see a difference.
2**2 means 2 squared (2^2)
2*2 mean 2 times 2 (2x2)
In this case they happen to have the same value, but...
3**3*4 != 3*3*4
For visual learners.........................
To specifically answer your question Why is the code1 used if we can use code2? I might suggest that the programmer was thinking in a mathematically broader sense. Specifically, perhaps the broader equation is a power equation, and the fact that both first numbers are "2" is more coincidence than mathematical reality. I'd want to make sure that the broader context of the code supports it being var = x * x * y in all cases, rather than in this specific case alone. This could get you in big trouble if x is anything but 2.
2**2 = 2 power-of 2
2*2 = 2 times 2
The ** operator in Python is really "power;" that is, 2**3 = 8.
The top one is a "power" operator, so in this case it is the same as 2 * 2 equal to is 2 to the power of 2. If you put a 3 in the middle position, you will see a difference.
A double asterisk means to the power of. A single asterisk means multiplied by. 22 is the same as 2x2 which is why both answers came out as 4.
Power has more precedence than multiply, so:
2**2*3 = (2^2)*3
2*2*3 = 2*2*3