Побитовое И, «a & b», следует рассматривать как
function _bitwise_and(A,B):
# A and B are Python expressions
# which result in lists of 1's and 0's
a = A.evaluate()
b = B.evaluate()
return [ 1 if abit==1 and bbit==1 else 0 for abit,bbit in zip(a,b)]
, поэтому графически
a: ... 0 1 1 0
b: ... 1 0 1 0
--------
a&b ... 0 0 1 0 <- each bit is 1 if-and-only-if the
corresponding input bits are both 1
и в результате получается список битов, упакованных вцелое число.
.
Логические AND, "a и b", вместо этого следует рассматривать как
function _and(A,B):
# A and B are Python expressions which result in values having truthiness
a = A.evaluate()
if is_truthy(a):
b = B.evaluate()
return b
else:
return a
.
Примечание: еслирезультат A ложен, B никогда не оценивается - поэтому, если выражение B имеет ошибку при вычислении, поразрядно И приведет к ошибке , тогда как логическое И не будет .
Это основа для общей идиомы Python,
while (offset in data) and test(data[offset]):
do_something_to(data[offset])
next offset
... потому что data [offset] оценивается только в том случае, если offset является полезным (не генерирующим ошибки) значением.
Используя '&' вместо 'и', вы гарантируете ошибку, оценивая данные [last_offset + 1] в конце вашего цикла.
.
Конечно, этоможно было бы избежать с помощью другой распространенной идиомы:
for ch in string if ch=='c':
do_something_to(ch)
, которая полностью исключает проблемы IndexError.