Python 3 порядок тестирования не определен - PullRequest
0 голосов
/ 17 января 2011
string='a'
p=0
while (p <len(string)) & (string[p]!='c') :
                    p +=1

print ('the end but the  process  already died ')
       while (p <1) & (string[p]!='c') :
IndexError: string index out of range

Я хочу проверить условие до конца строки (пример длины строки = 1), почему обе части и выполнены, если условие уже ложно!пока p < len(string).вторую часть даже не нужно выполнять.если это делает много производительности может быть потеряно

Ответы [ 3 ]

9 голосов
/ 17 января 2011

Вы не используете правильный логический and. Используйте его, и вы не увидите эту проблему. То, что вы используете (&), является побитовым сравнением, которое оценивает обе стороны.

1 голос
/ 17 января 2011

Побитовое И, «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.

0 голосов
/ 17 января 2011

Вам необходимо использовать логические операторы и / или, а не побитовые операторы & и |

...