3

I've been tinkering a little with Python operators and came across something I'm not sure about.

If I perform a bitwise operation (&, |) on 2 integers I will get unsurprisingly their bitwise value. Meaning:

>>> a = 11
>>> b = 3
>>> a & b
3

This is because it performs bitwise AND on the binary representation of these numbers.

However, if I use the built in and operator I will get the second variable, irrespective of its type:

>>> b and a
11
>>> 'b' and 'a'
'a'

Why is it so?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
tHeReaver
  • 215
  • 1
  • 10

4 Answers4

11

Logical operators operate on the truthiness of an object. Every object has truth value, unless it has a __bool__ method that is explicitly overridden to raise an error. The major difference between a and b (logical) and a & b (bitwise) is that the former apply to any objects, while the latter only apply to numeric types that support bitwise operations1.

Python's logical operators are specifically designed to return the result of the last object evaluated:

  • a and b: Returns a Falsy a, or b (if a is truthy)
  • a or b: Returns a Truthy a, or b (if a if falsy)

From the tutorial:

The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.

This property is used semi-idiomatically to check values before accessing them. For example, if a list must contain an element, you can do something like

if x and x[0] == value:
    # ...

This will not raise an error, because if x is Falsy (empty), the and expression will return x instead of x[0] == value.


1 Set-like objects also support & as the intersection operator. This is conceptually similar to what the bitwise operator does for integers (you can think of bits as sets), and in no way detracts from the rest of the answer.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • 2
    Many types lack a `__bool__` method. If `__bool__` is missing, a non-zero return value from `__len__` indicates truthiness. If `__len__` is also missing, the object is considered truthy. (For example, `list` defines `__len__` but not `__bool__`, and `object` defines neither.) – chepner Aug 23 '21 at 16:51
  • @chepner. Sorry, hasty phrasing. Fixed now – Mad Physicist Aug 23 '21 at 16:53
  • No problem. I think I'll leave the comment, if only because I'm not sure it's worth delving into the whole `__len__`-vs-`__bool__` issue in the answer itself. – chepner Aug 23 '21 at 16:54
  • @chepner. Thanks. It does enhance the answer. – Mad Physicist Aug 23 '21 at 16:54
  • Nitpicking, but `&` isn't only defined for numeric types, it's also defined for set-like types like `set` (ofc) and dict keys, as well as NumPy array and Pandas Series/DataFrame. – wjandrea Nov 07 '22 at 17:59
  • 1
    @wjandrea. Good call. I added a footnote. – Mad Physicist Nov 07 '22 at 18:20
3

The documentation says:

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Since Python considers the boolean value for both strings and non-zero integers to be True, x and y would imply True and True, and since the boolean of the first statement is not False, the second statement is evaluated and the resulting value (which is the value of the second term) is returned.

Suneesh Jacob
  • 806
  • 1
  • 7
  • 15
2

The first case with and:

>>> b and a #(11 and 3, both the values evaluates to be true because non-zero)
11
>>> 'b' and  'a' #(again both are evaluated to be true because non-empty)

For and all the conditions need to be True, so checked upto the last item if the previous evaluates to be True, hence you get the last item.

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
0

Case 1 : A and B
here consider A ,B both are non zeroes for and it checks both A,B that is it first evaluates A if in A after conversion in binary(for understanding consider positive integers , A > 0 and B > 0) whether 1 is present or not , if yes it moves to B and returns B as output. Because and checks both A and B.

A or B

here it checks the A as same as above if it has 1 after converting in to binary, if A is True it return A (obviously A > 0 so it return A only ).

case 2 : suppose Any 1 in A,B or both A,B are ZEROES I will try to explain in better way . I hope we all know truth tables for 'AND' and 'OR' and 'XOR'. Same thing happening here just replace 1's and 0's with any number, if you want you use only 1's and 0's to understand in better way.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 14 '21 at 21:24