# 'and' (boolean) vs '&' (bitwise) - Why difference in behavior with lists vs numpy arrays?

What explains the difference in behavior of boolean and bitwise operations on lists vs NumPy arrays?

I'm confused about the appropriate use of `&` vs `and` in Python, illustrated in the following examples.

``````mylist1 = [True,  True,  True, False,  True]
mylist2 = [False, True, False,  True, False]

>>> len(mylist1) == len(mylist2)
True

# ---- Example 1 ----
>>> mylist1 and mylist2
[False, True, False, True, False]
# I would have expected [False, True, False, False, False]

# ---- Example 2 ----
>>> mylist1 & mylist2
TypeError: unsupported operand type(s) for &: 'list' and 'list'
# Why not just like example 1?

>>> import numpy as np

# ---- Example 3 ----
>>> np.array(mylist1) and np.array(mylist2)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
# Why not just like Example 4?

# ---- Example 4 ----
>>> np.array(mylist1) & np.array(mylist2)
array([False,  True, False, False, False], dtype=bool)
# This is the output I was expecting!
``````

This answer and this answer helped me understand that `and` is a boolean operation but `&` is a bitwise operation.

I read about bitwise operations to better understand the concept, but I am struggling to use that information to make sense of my above 4 examples.

Example 4 led me to my desired output, so that is fine, but I am still confused about when/how/why I should use `and` vs `&`. Why do lists and NumPy arrays behave differently with these operators?

Can anyone help me understand the difference between boolean and bitwise operations to explain why they handle lists and NumPy arrays differently?

93

`and` tests whether both expressions are logically `True` while `&` (when used with `True`/`False` values) tests if both are `True`.

In Python, empty built-in objects are typically treated as logically `False` while non-empty built-ins are logically `True`. This facilitates the common use case where you want to do something if a list is empty and something else if the list is not. Note that this means that the list [False] is logically `True`:

``````>>> if [False]:
...    print 'True'
...
True
``````

So in Example 1, the first list is non-empty and therefore logically `True`, so the truth value of the `and` is the same as that of the second list. (In our case, the second list is non-empty and therefore logically `True`, but identifying that would require an unnecessary step of calculation.)

For example 2, lists cannot meaningfully be combined in a bitwise fashion because they can contain arbitrary unlike elements. Things that can be combined bitwise include: Trues and Falses, integers.

NumPy objects, by contrast, support vectorized calculations. That is, they let you perform the same operations on multiple pieces of data.

Example 3 fails because NumPy arrays (of length > 1) have no truth value as this prevents vector-based logic confusion.

Example 4 is simply a vectorized bit `and` operation.

Bottom Line

• If you are not dealing with arrays and are not performing math manipulations of integers, you probably want `and`.

• If you have vectors of truth values that you wish to combine, use `numpy` with `&`.

Tuesday, June 1, 2021

49

Those are the bitwise AND and bitwise OR operators.

``````int a = 6; // 110
int b = 4; // 100

// Bitwise AND

int c = a & b;
//   110
// & 100
// -----
//   100

// Bitwise OR

int d = a | b;
//   110
// | 100
// -----
//   110

System.out.println(c); // 4
System.out.println(d); // 6
``````

Thanks to Carlos for pointing out the appropriate section in the Java Language Spec (15.22.1, 15.22.2) regarding the different behaviors of the operator based on its inputs.

Indeed when both inputs are boolean, the operators are considered the Boolean Logical Operators and behave similar to the Conditional-And (`&&`) and Conditional-Or (`||`) operators except for the fact that they don't short-circuit so while the following is safe:

``````if((a != null) && (a.something == 3)){
}
``````

This is not:

``````if((a != null) & (a.something == 3)){
}
``````

"Short-circuiting" means the operator does not necessarily examine all conditions. In the above examples, `&&` will examine the second condition only when `a` is not `null` (otherwise the whole statement will return false, and it would be moot to examine following conditions anyway), so the statement of `a.something` will not raise an exception, or is considered "safe."

The `&` operator always examines every condition in the clause, so in the examples above, `a.something` may be evaluated when `a` is in fact a `null` value, raising an exception.

Tuesday, June 1, 2021

16

May not be the best answer, but this works...

``````import numpy as np
np.int32(1171855803) << 7
``````
Wednesday, September 1, 2021

73

Solved: to prevent default "Back" button behaivor it is enough to return 1 while handling key event:

``````int32_t app_handle_event(struct android_app* app, AInputEvent* event) {
if (AKeyEvent_getKeyCode(event) == AKEYCODE_BACK) {
// actions on back key
return 1; // <-- prevent default handler
};
// ...
return 0;
}
``````
Monday, September 13, 2021

85

T is a integer type, which I'm assuming is unsigned. Since this is C, it'll be fixed width, probably (but not necessarily) one of 8, 16, 32, 64 or 128. The fragment `(T)~(T)0` that appears repeatedly in that code sample just gives the value 2**N-1, where N is the width of the type T. I suspect that the code may require that N be a multiple of 8 for correct operation.

Here's a direct translation of the given code into Python, parameterized in terms of N, the width of T in bits.

``````def count_set_bits(v, N=128):
mask = (1 << N) - 1

v = v - ((v >> 1) & mask//3)
v = (v + (v >> 4)) & mask//255*15
return (mask & v * (mask//255)) >> (N//8 - 1) * 8
``````

Caveats:

(1) the above will only work for numbers up to 2**128. You might be able to generalize it for larger numbers, though.

(2) There are obvious inefficiencies: for example, 'mask//15' is computed twice. This doesn't matter for C, of course, because the compiler will almost certainly do the division at compile time rather than run time, but Python's peephole optimizer may not be so clever.

(3) The fastest C method may well not translate to the fastest Python method. For Python speed, you should probably be looking for an algorithm that minimizes the number of Python bitwise operations. As Alexander Gessler said: profile!

Friday, September 24, 2021