Как мне вырваться из вложенного цикла в python?

#python #pyautogui

Вопрос:

Я запускаю цикл, если на экране найдено изображение.png.

Это работает, он зацикливается до тех пор, пока не будет найден файл.png, а затем запускается Основной цикл поиска.

Как только сработает Основной цикл поиска, я хочу выйти в предыдущий цикл и начать снова.

Я попытался сделать перерыв там, где, по моему мнению, он должен остановиться и вернуться к первому циклу, но он не прерывается; Основной цикл поиска продолжается.

Я думал, что добавление перерыва после моего » еще «остановит этот цикл, когда» еще » будет выполнено.

Я использую подсчеты только в целях тестирования, цель состоит в том, чтобы это были бесконечные циклы.

 while CountA <20:

        if pyautogui.locateOnScreen('a.png') != None:

        image_list = []
        # Get list of all files in current directory
        directory = os.listdir()

        # Find files that end with .png or .jpg and add to image_list
        for file in directory:
            if file.endswith('.png') or file.endswith('.jpg'):
                image_list.append(file)

        #Loop through the list to find all the images
            count = 0
            while count <20:   

                #Main Find Loop
                for image in image_list:
                    name = image
                    Found = pyautogui.locateCenterOnScreen(image)
                    if Found != None:
                        pyautogui.moveTo(1700,1000,0.1)
                        pyautogui.click()
                    else:
                        pyautogui.moveTo(1415,1000,0.1)
                        pyautogui.click()
                        break

            count = count   1

CountA = countA   1
 

Комментарии:

1. Когда основной цикл поиска прерывается ( for цикл, который имеет «основной цикл поиска» прямо над ним, верно?), внешний цикл ( while count < 20 ) действительно продолжается. Вы говорите о другой внешней петле? Здесь у вас есть четыре уровня вложенного цикла, поэтому вам нужно быть более конкретным, чем «выход в предыдущий цикл».

2. Поместите внутренние циклы в функцию и return .

3. Ладно, урок первый: я думал, что у меня только два уровня петель. Я только считал while CountA и while count как мои петли. Имея это в виду, я хочу остановить while count цикл и запустить CountA цикл.

4. Как предположил @samwise в своем комментарии, вам нужно быть более точным в том, что именно вы подразумеваете под «выходом в предыдущий цикл». Я бы предложил ввести логическое значение, назвать его, возможно, X, а затем сделать его = True вместо того, чтобы прерывать цикл. Теперь в основном предыдущем цикле (как вы его назвали) выйдите из него, если X истинно.

Ответ №1:

Основываясь на ответе, который вы написали под своим основным постом, этот код будет работать для вашего варианта использования.

 while CountA <20:

        if pyautogui.locateOnScreen('a.png') != None:

        image_list = []
        # Get list of all files in current directory
        directory = os.listdir()

        breaking_bool = False
        # Find files that end with .png or .jpg and add to image_list
        for file in directory:
            if breaking_bool is True:
                break
            if file.endswith('.png') or file.endswith('.jpg'):
                image_list.append(file)

        #Loop through the list to find all the images
            count = 0
            while count <20 and breaking_bool is False:   

                #Main Find Loop
                for image in image_list:
                    name = image
                    Found = pyautogui.locateCenterOnScreen(image)
                    if Found != None:
                        pyautogui.moveTo(1700,1000,0.1)
                        pyautogui.click()
                    else:
                        pyautogui.moveTo(1415,1000,0.1)
                        pyautogui.click()
                        breaking_bool = True
                        break

            count = count   1

CountA = countA   1
 

Идея состоит в том, чтобы ввести логическую переменную (я назвал ее breaking_bool), которая сообщала бы «предыдущему внешнему циклу», как вы его назвали, остановиться, когда это правда.

Ответ №2:

Самый простой способ вырваться из внешнего цикла изнутри внутреннего цикла-это не иметь внешнего цикла.

Поскольку в вашем внешнем цикле на самом деле ничего не происходит, вы можете заменить его itertools.cycle (поскольку while True , как вы сказали, счетчик предназначен только для отладки) или выражением генератора для ограниченных повторов (или комбинацией itertools.repeat и chain.from_iterable , но я думаю, что выражение генератора проще).

Пример: Цикл, хотя image_list и бесконечный, пока условие не станет истинным:

 for image in itertools.cycle(image_list):
    Found = pyautogui.locateCenterOnScreen(image)
    if Found != None:
        pyautogui.moveTo(1700,1000,0.1)
        pyautogui.click()
    else:
        pyautogui.moveTo(1415,1000,0.1)
        pyautogui.click()
        break
 

Пример: Повторите цикл image_list не более 20 раз или до тех пор, пока условие не станет истинным:

 for image in (img for _ in range(20) for img in image_list):
    Found = pyautogui.locateCenterOnScreen(image)
    if Found != None:
        pyautogui.moveTo(1700,1000,0.1)
        pyautogui.click()
    else:
        pyautogui.moveTo(1415,1000,0.1)
        pyautogui.click()
        break
 

Комментарии:

1. Я думаю, что мне есть о чем подумать с этим сейчас! Я использую 1-й цикл для поиска изображения, которое появляется только иногда, чтобы затем запустить 2-й цикл. Я не могу запустить 2-й цикл 24/7, потому что мне нужно будет сделать еще много работы. Ваш подход, я думаю, лучше в долгосрочной перспективе, я думаю. Я предполагаю, что меньшее количество циклов должно быть лучше для скорости.

2. @L23P Даже с cycle ним не будет работать вечно, так как вы все равно break выйдете из цикла, как только изображение будет найдено. О скорости выполнения: Не имеет значения, есть ли у вас один или два цикла, имеет значение код, который выполняется в этих циклах, и это одинаково в каждом случае.