'Python - why '&' and 'and' operators provide different results though evaluate the condition with same result

I have just started learning Python. I have come across the below problem. As shown below, I am writing a same statement once using '&' operator and then using 'and' operator. Though both of these operators evaluate the 'if' condition to the same Boolean output,'True' (True 'and' True is True and also True & True is True), why are the results different? Why is '&' giving wrong answer? Appreciate any clarifications.

a = 70
b = 40
c = 60

x = a if a>b and a>c else b if b>c else c
print('Max value with "and":', x)

x = a if a>b & a>c else b if b>c else c
print('Max value with "ampersand":', x)

The output is:

Max value with "and": 70

Max value with "ampersand": 60



Solution 1:[1]

why are the results different? Why is '&' giving wrong answer?

Because they're completely different operators with completely different semantics and completely different precedence: & applies before > which applies before and.

So when you write a > b and a > c it's parsed as (a > b) and (a > c).

But when you write a > b & a > c, it's parsed as a > (b & a) > c.

There's an other difference which is not relevant here but would be a factor in other context: and (and or) are lazy operators, meaning they will evaluate their left operands, then do their thing, and only then evaluate the second operand. & however is a normal "eager" operator, it evaluates both operands and only then applies whatever it does.

Finally, and this is of course the biggest difference: and works on everything and is non-overridable; & only works on types which specifically support it, and does whatever it was defined as (for integers it's a bitwise AND, but for sets it's intersection).

Solution 2:[2]

We can use the std::mem::size_of_val and pass the reference of each fields. The returned type is usize which itself can be 4 or 8 bytes based on the target machine.

let entry = MemTableEntry{
    key: b"Hello".to_vec(),
    value: Some(b"World".to_vec()),
    timestamp: 123u128,
    deleted: false
};

let size = mem::size_of_val(&entry.key)
    + mem::size_of_val(&entry.value)
    + mem::size_of_val(&entry.timestamp)
    + mem::size_of_val(&entry.deleted);

assert_eq!(65, size);

Note: Please look at the @Caesar's comment below about memory.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Masklinn
Solution 2