Since they are basically equivalent, you could also consider the way you read/think about the code:
if a == 5 and b == 5:
# do something
can be read as "if a equals 5 and b equals 5, then do ...". You have to think/conclude, that then also a will be equal to b.
This is opposite to the next example:
if a == b and b == 5:
# do something
This reads as "if a is equal to b and b equal to 5" and you have to conclude that then also a will be equal to 5
This is why I prefer the last example:
if a == b == 5:
# do something
If you are familiar with Python (thanks to Itzkata) it is immediately clear that all three things must be equal (to 5). If however people with less experience in Python (but programming skills in other languages) see this, they might evaluate this to
if (a == b) == 5:
which would compare the boolean result of the first comparison with the integer 5, which is not what Python does and might lead to different results (consider for example with a=0, b=0: a==b==0 is true while (a==b) == 0 is not!
The manual says:
There are eight comparison operations in Python. They all have the
same priority (which is higher than that of the Boolean operations).
Comparisons can be chained arbitrarily; for example, x < y <= z is
equivalent to x < y and y <= z, except that y is evaluated only once
(but in both cases z is not evaluated at all when x < y is found to be
false).
There might even be a difference, for example if evaulating b in your example would have a side effect.
Regarding transitivity, you are right.
inttype. And as far as which is 'better' that's up to the programmer for clarity and readability.a < b > 5anda > b == 5are possible, too (I noticed the docs Jasper quoted say "Comparisons can be chained arbitrarily"). But I wouldn't recommend them.a < b and b > 5, but that's just me. I agree thata > b == 5is a little bit shaky though..a < b < 5.a < b > 5is likea < b and 5 < b. I'd only chain</<=operators, or only==, since those are the clearest operations