Оператор Else, выполняющий даже оператор IF, имеет значение TRUE

У меня проблема с языком Python, описанная в заголовке.

 for slovo in slova:
        if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
            for i in range (len(randRijec)):
                if slovo["name"] in randRijec[i]:
                    if i == 0:
                        slovo1 = randRijec[i].upper()
                        prvoSlovo = 1
                    ...
                    ...
                else:
                    pogresnoBrojac += 1
            slova.remove(slovo)

Таким образом, даже если этот оператор IF истинен, выполняется оператор ELSE! Однако оператор else следует пропустить, если выполняется оператор if.

Как решить эту проблему?

p.s. У меня была эта проблема несколько раз раньше, и я не мог ее решить...


person lbartolic    schedule 24.03.2013    source источник
comment
Включите SSCCE (sscce.org), демонстрирующий проблему.   -  person NPE    schedule 24.03.2013
comment
Вы имеете в виду, что выполняются оба блока или только блок else? Вы уверены, что отступ правильный?   -  person wRAR    schedule 24.03.2013
comment
проверьте свой отступ.   -  person Thanakron Tandavas    schedule 24.03.2013
comment
отступ правильный, да, оба блока выполняются   -  person lbartolic    schedule 24.03.2013
comment
а почему (-1) если вопрос задан правильно? спасибо кстати   -  person lbartolic    schedule 24.03.2013
comment
Легко разоблачить, добавив time.sleep и оператор count up print, чтобы увидеть, при каком числе в цикле for срабатывает ваш else (также известный как грубая отладка). ваш ответ далек от pythonic.   -  person ZF007    schedule 12.08.2019


Ответы (4)


У вас есть смесь вкладок и пробелов в вашем коде:

Запуск cat -A test.py (в Unix) дает

     for slovo in slova:$
            if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):$
                for i in range (len(randRijec)):$
                    if slovo["name"] in randRijec[i]:$
                        if i == 0:$
                            slovo1 = randRijec[i].upper()$
                            prvoSlovo = 1$
^I^I^I^I^I^I...$
^I^I^I^I^I^I...$
                    else:$
                        pogresnoBrojac += 1$
                slova.remove(slovo)$

^I обозначают вкладки.

Таким образом, блок else не интерпретируется как находящийся на том уровне отступа, на котором он кажется.

Ваш код Python никогда не должен смешивать вкладки и пробелы для отступов. Вы можете проверить, что ваш скрипт не смешивает табуляции и пробелы, запустив python -t script.py.

В Python вы должны использовать только пробелы или только табуляции для отступов. PEP8 рекомендует использовать только пробелы.

Вы можете преобразовать вкладки в пробелы с помощью программы reindent.py.

person unutbu    schedule 24.03.2013
comment
Нет сомнения, что это очень хороший совет. Однако разве в этом примере if и else не имеют отступа с использованием только пробелов? Я уверен, что мне не хватает чего-то очевидного здесь. - person NPE; 24.03.2013
comment
спасибо за это, но я не могу решить эту проблему. когда я делаю отступ в правильном направлении, я продолжаю получать эту проблему. - person lbartolic; 24.03.2013
comment
@NPE: вы правы; это не может быть реальной проблемой. Однако по моему опыту, когда соблюдаются основные правила, загадочные ошибки обычно исчезают. - person unutbu; 24.03.2013
comment
@lucro93: В этом случае вам действительно нужно показать нам исполняемый код, в котором проявляется проблема. - person unutbu; 24.03.2013
comment
я нашел решение! я отвечу - person lbartolic; 24.03.2013

Таким образом, даже если это утверждение IF истинно, выполняется выражение ELSE!

Я могу заверить вас, что это не то, что происходит.

Я заметил, что в схеме вашего кода if находится внутри цикла for. Убедитесь, что в вашем реальном коде else случайно не выровнено с for вместо if. Я видел эту ошибку не раз.

В Python for-else является допустимой конструкцией. Например, следующий код вполне корректен для Python:

for i in range(10):
    if i < 100:
        pass
else:
    print 'In else clause'

При запуске это выводит In else clause.

Сравните это со следующим, который ничего не печатает при запуске:

for i in range(10):
    if i < 100:
        pass
    else:
        print 'In else clause'
person NPE    schedule 24.03.2013
comment
спасибо за ответ, но мой оператор else выровнен с оператором if, если вы хотите сказать, что оператор else выровнен с оператором for one? - person lbartolic; 24.03.2013
comment
else выполняется в другом цикле for. Смотрите мой основной комментарий к вопросу. - person ZF007; 12.08.2019

Это давний вопрос, и я наткнулся на него, когда решал ту же проблему — решение было на самом деле довольно глупым и, скорее всего, так оно и было — поскольку это цикл for, он перебирает каждый элемент списка, если даже если один из этих элементов не соответствует условию if, он автоматически вызовет else — довольно очевидное, но новичкам легко его не заметить. Ну, по крайней мере, это было проблемой в моем случае :)

person Jan Piątkowski    schedule 11.08.2019

Следующее решение устранило мою проблему:

    for slovo in slova:
        if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
            xy = 0
            for i in range (len(randRijec)):
                if slovo["name"] in randRijec[i]:
                    xy = 1
                    if i == 0:
                        slovo1 = randRijec[i].upper()
                        prvoSlovo = 1
                        break
                    if i == 1:
                        slovo2 = randRijec[i].upper()
                        drugoSlovo = 1
                        break
            slova.remove(slovo)
            if xy == 0:
                pogresnoBrojac += 1

    ...
    ...
    ...

    xy = 1
    pygame.display.update()
    time.tick(value)

Итак, я только что добавил этот счетчик xy, который заставляет мой код работать так, как он должен работать. Когда выполняется оператор IF, xy становится 1, если оператор IF не выполняется, xy устанавливается в 0, а затем выполняется этот оператор "else". В конце кода xy снова устанавливается в 1, чтобы предотвратить выполнение этого блока "else" (если xy == 0).

person lbartolic    schedule 24.03.2013