Как остановить python бесконечный л oop? - PullRequest
0 голосов
/ 09 мая 2020
import random   
n=int(input())  

array=[]     
for i in range(0,n): 
    flag=True    
    while flag:
           print("flag=",flag)
           a=[]
           for j in range(0,n):
               if i!=j:
                  w= random.randint(0,1)
                  print("random=",w)
                  if w==1 and i<j:
                     v=random.randint(1,10)
                     a.append(v)
                  else:
                      a.append(0)
               elif i==j:
                    a.append(0)
           print(a)
           if a.count(0) !=n:
              print("a.count(0)=",a.count(0))
              flag=False
              print("flag value=",flag)
      array.append(a)
print(array) 

В этой программе, если количество нулей не равно n, она должна разбить l oop и добавить его в матрицу, но это l oop выполняется бесконечное количество раз, значение флага равно присвоено значение false, но значение флага по-прежнему будет истинным. Эта программа должна генерировать по крайней мере одно случайное целое число для каждой строки, поэтому я проверяю, не равны ли нули ни одному из столбцов, не нарушающих l oop. Есть ли способ сделать это?

так что, пожалуйста, скажите мне, как остановить это l oop, когда количество нулей не равно вводу n?

Ответы [ 2 ]

0 голосов
/ 12 мая 2020

Python не поддерживает бесконечные циклы, так как имеет защитные меры против этого.

0 голосов
/ 09 мая 2020

Хорошо, во-первых, давайте исправим отступы и проблемы с PEP8 и добавим некоторые аннотации типов, чтобы мы могли видеть, что происходит. (Добавление аннотаций типов помогло мне исправить отступ, поскольку попытка автоисправления привела к синтаксическим ошибкам, которые мне пришлось go вернуть и исправить.) Я просто удалил элемент Graph, поскольку вы не используете его в этом коде. в любом случае, и я не знал, откуда этот импорт.

import random
from typing import List

n = int(input())
array: List[List[int]] = []
for i in range(0, n):
    flag = True
    while flag:
        print("flag=", flag)
        a: List[int] = []
        for j in range(0, n):
            if i != j:
                w = random.randint(0, 1)
                print("random=", w)
                if w == 1 and i < j:
                    v = random.randint(1, 10)
                    a.append(v)
                else:
                    a.append(0)
            elif i == j:
                a.append(0)
        print(a)
        if a.count(0) != n:
            print("a.count(0)=", a.count(0))
            flag = False
            print("flag value=", flag)
    array.append(a)
print(array)

Теперь давайте посмотрим на результат:

2
flag= True
random= 0
[0, 0]
flag= True
random= 1
[0, 6]
a.count(0)= 1
flag value= False
flag= True
random= 0
[0, 0]
flag= True
random= 1
[0, 0]
flag= True
random= 0
[0, 0]
flag= True
random= 0
[0, 0]
flag= True

Итак, мы сломаем внутреннюю while l oop в первый раз через for i l oop (i = 0), но мы возвращаемся и перезапускаем его на каждой итерации for i, а во второй раз (i = 1) мы всегда заканчиваем вверх с a == [0] * n. Когда я пробовал это с более высокими значениями n, казалось, что мы всегда оказываемся в этом состоянии.

Итак, что мы делаем в этом for j l oop, который всегда приводит к заполнению массива нулей, когда мы на последней i? Что ж, все сводится к следующему блоку:

                w = random.randint(0, 1)
                print("random=", w)
                if w == 1 and i < j:
                    v = random.randint(1, 10)
                    a.append(v)
                else:
                    a.append(0)

Оба i и j являются итерациями одного и того же range(n). Когда i находится на последней итерации (т.е. i == n - 1), тогда никогда невозможно будет иметь i < j, потому что i уже имеет максимальное значение, которое может иметь любой из них. Это означает, что мы будем всегда делать a.append(0) независимо от значения w, и, следовательно, всегда в итоге получим массив всех нулей независимо от того, сколько раз мы go через это, а l oop.

На последней i итерации flag остается True, потому что всегда будет верно, что a.count(0) == n, и поэтому while flag l oop в последний раз на этом for i l oop никогда не прекратится.

Один из способов помочь себе это доказать - просто добавить assert, например:

                if w == 1 and i < j:
                    # This block is the only thing that can ever set flag to False!
                    assert i < n - 1, "We never get here on the last loop!"
                    v = random.randint(1, 10)
                    a.append(v)

и заметить, что это никогда приводит к AssertionError.

...