Как остановить цикл в питоне: Циклы for и while, операторы break и continue, волшебное слово else

циклы — Python как остановить цикл по клику пункта меню?

Одна опечатка и одна принципиальная ошибка.

Опечатка в присваивании:

    if work:
        work==False   # должно быть просто =

А ошибка в том, что вы снова вызываете move_clockwise() в конце функции def move_counterclockwise(). В результате функции уходят в рекурсию и никогда не возвращаются в цикл проверки условия на останов:

    while work:
        move_clockwise()

Ну и work = True надо бы добавить в начало def start(event):. Чтобы можно было снова запустить движение овала.


Ну а вообще, код можно подсократить. И останавливаться мгновенно.

from tkinter import *
import random
import time
#from PIL import ImageTk, Image
root = Tk()
root.title("Лабораторная работа №4")
root.geometry('360x360')
width=360
height=360
sleep=0.02
step=15
work=False
c = Canvas(root, width=width, height=height, bg="white")
c.place(x = 0, y = 0)
oval = c. create_oval(0, 0, 30, 30, fill='green')
def move(figure):
    while True:
        for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1),  # по часовой
                                    (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
            for i in range(((height if vertical else width) - 30) // step):
                if not work: 
                    c.coords(figure, 0, 0, 30, 30)
                    return
                c.move(figure, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
                root.update()
                time.sleep(sleep)
def start(event):
    global work
    if not work:
        work = True
        move(oval)
def stop():
    global work
    work = False
#Заполнение матрицы
for x in range(6):
    for y in range(6):
        text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99)))
c.bind('<Double-Button-1>', start)
menu=Menu(root)
root.config(menu=menu)
menu.
add_command(label="Stop", command=stop) root.mainloop()

К тому же задание довольно невнятное. С учётом того, что движение должно происходить с дискретом 0.8 секунды (а это довольно большая пауза), возможно имелось ввиду, что овал должен прыгать по элементам матрицы. И в таком случае time.sleep() вообще применять нельзя, т.к. он будет фризить интерфейс на это время. Нужно использовать функцию after() для отложенного запуска следующего перемещения. Например, с использованием генератора, код может выглядеть так:

from tkinter import *
import random
import time
#from PIL import ImageTk, Image
root = Tk()
root.title("Лабораторная работа №4")
sleep = 0.8
step = 60
oval_size = 40
matrix_size = {"W":6, "H":6} # width, height
offset = (step - oval_size) // 2
work = False
root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
c.place(x = 0, y = 0)
oval = c.
create_oval(offset, offset, offset + oval_size, offset + oval_size) def move(gen=None): if work: next(gen) root.after(int(sleep*1000), lambda: move(gen)) def move_generator(): while True: for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой for i in range(matrix_size["H" if vertical else "W"] - 1): c.move(oval, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment) yield def start(event): global work if not work: work = True move(move_generator()) def stop(): global work work = False c.coords(oval, offset, offset, offset + oval_size, offset + oval_size) #Заполнение матрицы for x in range(6): for y in range(6): text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99))) c.bind('<Double-Button-1>', start) menu=Menu(root) root.
config(menu=menu) menu.add_command(label="Stop", command=stop) root.mainloop()

Оно же без использования генератора.

from tkinter import *
import random
import time
root = Tk()
root.title("Лабораторная работа №4")
sleep = 0.8
step = 60
oval_size = 40
matrix_size = {"W":6, "H":6} # width, height
offset = (step - oval_size) // 2
work = False
root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
c.place(x = 0, y = 0)
oval = c.create_oval(offset, offset, offset + oval_size, offset + oval_size)
movements = []
for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1),  # по часовой
                            (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
    for i in range(matrix_size["H" if vertical else "W"] - 1):
        movements.append(((0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment))
def move(pos=0):
    if work: 
        c.
move(oval, *movements[pos]) root.after(int(sleep*1000), lambda: move( (pos+1) % len(movements) )) def start(event): global work if not work: work = True move() def stop(): global work work = False c.coords(oval, offset, offset, offset + oval_size, offset + oval_size) #Заполнение матрицы for x in range(6): for y in range(6): text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99))) c.bind('<Double-Button-1>', start) menu=Menu(root) root.config(menu=menu) menu.add_command(label="Stop", command=stop) root.mainloop()

python — Как выйти из двух вложенных циклов

Ищу циклом текущего пользователя компьютера в локальной сети

def scan_Lan():
    ip_list = ['192.168.4.']
    i = 50
    while i <= 240:
        scan_ip = ip_list[0] + str(i)
        response = subprocess.Popen(["ping", "-n", "1", "-w", "200", scan_ip]).wait()
        if(response == 0):
            try:
                wql = 'SELECT *  FROM Win32_computerSystem'
                c = wmi. WMI(scan_ip, user='office\admin', password='fff')
                for item in c.query(wql):
                    currentUser = str(item.UserName)
                    print(currentUser)
                    if(currentUser == "ivanov"):
                        print(scan_ip)
                        break
            except:
                   print("-")
        i += 1
    print("end")
scan_Lan()

Все хорошо работает, но хочу после поиска выходить полностью из цикла while, как это сделать? Поставил вот здесь

 print(scan_ip)
 break

но он по всей видимости выходит только из for, а как сделать глобальный break?

  • python
  • python-3.x

1

break прекращает только вложенный цикл. Внешний цикл продолжает работать. Используйте return, когда результат найден в вашем случае:

if current_user == 'ivanov':
    return scan_ip

Можно сделать так

    while i <= 240:
        scan_ip = ip_list[0] + str(i)
        response = subprocess. Popen(["ping", "-n", "1", "-w", "200", scan_ip]).wait()
        if(response == 0):
            try:
                wql = 'SELECT *  FROM Win32_computerSystem'
                c = wmi.WMI(scan_ip, user='office\admin', password='fff')
                for item in c.query(wql):
                    currentUser = str(item.UserName)
                    print(currentUser)
                    if(currentUser == "ivanov"):
                        print(scan_ip)
                        break
                else: 
                  i += 1  # сюда зайдет, если цикл завершился полностью(то есть не было найдено)
                  print("end")
                  continue;
            except:
                   print("-")
        break; # сюда попадем и прервем большой цикл, если во внутреннем был найден объект

Вот более простой пример для понимания

for x in xrange(10):
    for y in xrange(10):
        for z in xrange(10):
            print x,y,z
            if x*y*z == 30:
                break # прерываем внутренний цикл
        else:
            continue # продолжаем, если внутренний цикл не был прерван
        break # внутренний цикл был прерван, прерываем и этот цикл
    else:
        continue
    break

Используйте флаг (булево значение) для выхода из циклов. При входе в условие currentUser == «ivanov» меняйте его значение на положительное, делайте break, а в основном цикле установите условие while i <= 240 and not result, тогда цикл будет завершен, как только result станет истиной.

Глобального break, для выхода из всех циклов, не существует.

a:

list_ = [1, 2, 3, 4, 5]
check = True
while check:
    for v in list_:
        if v == 3:
            check = False
            break
        else:
            print(v)

b:

list_ = [1, 2, 3, 4]
try:
    while True:
        for v in list_:
            if v == 3:
                raise UserWarning
            else:
                print(v)
except UserWarning:pass

1

2

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Python выйти из цикла раньше –

спросил

Изменено 11 лет, 4 месяца назад

Просмотрено 65 тысяч раз

Как выйти из цикла раньше в Python?

 для а в б:
    если критерии в списке1:
        печатать "о нет"
        #Принудительный цикл, т. е. форсировать следующую итерацию, не продолжая
    someList.append(a)
 

Кроме того, в Java вы можете вырвать из цикла, есть ли эквивалент в Python?

  • питон
  • петли

1

продолжить и прервать то, что вы хотите. В этом отношении Python работает идентично Java/C++.

1

Во-первых, имейте в виду, что с пониманием списка можно делать то, что вы хотите. Таким образом, вы можете использовать что-то вроде:

 somelist = [a для a в b, если не a.criteria в otherlist]
 

Если вы хотите раньше выйти из цикла в Python, вы можете использовать break , как и в Java.

 >>> для x в xrange(1,6):
... напечатать х
... если х == 2:
...         сломать
...
1
2
 

Если вы хотите начать следующую итерацию цикла раньше, используйте continue , опять же, как в Java.

 >>> для x в xrange(1,6):
... если х == 2:
...         Продолжить
... напечатать х
...
1
3
4
5
 

Вот документация для break и continue . Это также охватывает else предложений для циклов, которые не запускаются, когда вы прерываете .

continue и break работают точно так же, как и в других языках программирования, за исключением того, что вы не можете разбить на метку (как, например, в Java). Это означает, что вы можете разорвать только один цикл за раз.

Взгляните на перерыв и продолжить .

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

python — Как я могу остановить цикл While?

Задать вопрос

спросил

Изменено 13 дней назад

Просмотрено 245 тысяч раз

Я написал цикл while в функции, но не знаю, как его остановить. Когда он не соответствует своему конечному условию, цикл просто продолжается вечно. Как я могу это остановить?

 определение_периода (вселенная_массива):
    период=0
    tmp=universe_array
    пока верно:
        tmp=apply_rules(tmp)#aplly_rules — это другая функция
        период+=1
        если numpy.array_equal(tmp,universe_array) имеет значение True:
            break #я хочу, чтобы цикл останавливался и возвращал 0, если
                     #период больше 12
    если период>12: # я написал эту строку, чтобы остановить его.. но кажется, что это
                   #не работает....помогите..
        вернуть 0
    еще:
        период возврата
 
  • питон
  • цикл while

4

просто сделайте правильный отступ в коде:

 def define_period(universe_array):
    период=0
    tmp=universe_array
    пока верно:
        tmp=apply_rules(tmp)#aplly_rules — это другая функция
        период+=1
        если numpy. array_equal(tmp,universe_array) имеет значение True:
            период возврата
        если период>12: # я написал эту строку, чтобы остановить его.. но, похоже, это не работает.... помогите..
            вернуть 0
        еще:
            период возврата
 

Вы должны понимать, что оператор break в вашем примере выйдет из бесконечного цикла, который вы создали с помощью , в то время как True . Поэтому, когда условие прерывания равно True, программа выйдет из бесконечного цикла и перейдет к следующему блоку с отступом. Поскольку в вашем коде нет следующего блока, функция завершается и ничего не возвращает. Итак, я исправил ваш код, заменив оператор break оператором return .

Следуя вашей идее использовать бесконечный цикл, это лучший способ написать его:

 определение_периода (вселенная_массива):
    период=0
    tmp=universe_array
    пока верно:
        tmp=apply_rules(tmp)#aplly_rules — это другая функция
        период+=1
        если numpy. array_equal(tmp,universe_array) имеет значение True:
            сломать
        если период>12: # я написал эту строку, чтобы остановить его.. но, похоже, это не работает.... помогите..
            период = 0
            сломать
    период возврата
 

3

 определение_периода (вселенная_массива):
    период=0
    tmp=universe_array
    в то время как период <12:
        tmp=apply_rules(tmp)#aplly_rules — это другая функция
        если numpy.array_equal(tmp,universe_array) имеет значение True:
            сломать
        период+=1
    период возврата
 

5

Оператор is в Python, вероятно, не делает того, что вы ожидаете. Вместо этого:

, если numpy.array_equal(tmp,universe_array) имеет значение True:
        сломать
 

Я бы написал так:

 if numpy.array_equal(tmp,universe_array):
        сломать
 

— это оператор , проверяющий идентичность объекта, что совсем не похоже на равенство.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *