-3

I wrote a really simple code to create some nested lists, and I got an unexpected problem, that while loop doesn't end. Have no idea what is wrong in it. If you have any clues, would much appreciate it)

import random

square = [0,0,0,0,0,0,0,0,0]
squares = []

def allsquares():
    for i in range(9):
        squares.append(square)
    return squares 

def autofill():
        for i in range(9):
            fn = random.randint(1,3)
            sn = random.randint(6,8)
            for s in range(fn,sn):
                print('Mary Sue')
                d = True
                while d:
                    x = random.randint(0,8)
                    print(x)
                    if squares[i][x] == 0:
                        d = False
                squares[i][x] = random.randint(1,9)
        return squares



allsquares()
autofill()
print(squares[2])
Malcador
  • 53
  • 9
  • 1
    well `squares[i][x] = random.randint(1,9)` is never going to be 0 so,..... – SuperStew Jan 08 '20 at 16:22
  • At the end of 1 loop you assign `squares[i][x] = random.randint(1,9)`. And without incrementing `i`, you check `squares[i][x] == 0` which you just mutated to not be 0. Eventually the i'th row is being filled up with random numbers 1-9 (none of which meet the condition of being 0) – Brian Jan 08 '20 at 16:23
  • That statement is out of the while loop, so it shouldn't be that... – toti08 Jan 08 '20 at 16:24
  • 1
    Have any idea what problem are you solving? Please explain the original problem. We never know. – Austin Jan 08 '20 at 16:25
  • @toti08, `squares[i][x] = random.randint(1,9)` is out of the loop but it very much matters. It's within the same for loop with a fixed `i`. The code doesn't get stuck in the while loop (at least initially) – Brian Jan 08 '20 at 16:26
  • @BrianJoseph right, I overlooked the inner for loop... – toti08 Jan 08 '20 at 16:27
  • Are you sure your indentation is correct? Could it be that the statement `squares[i][x] = random.randint(1,9)` is misplaced? – toti08 Jan 08 '20 at 16:28
  • I am doing random board generetor for sudoku) – Malcador Jan 08 '20 at 16:32
  • Not an answer, but `while True: ... if squares[i][x] == 0: break` is more idiomatic than using an extraneous variable `d`. – chepner Jan 08 '20 at 16:36
  • Note that `allsquares` is just filling a list with 9 references to the *same* list. It is not making copies. To create an a list of lists you need to do something like `squares = [[0] * 9 for _ in range(9)`. Note that this is a 1 liner so don't need any separate function or any global variables to do this. – Iguananaut Jan 08 '20 at 16:36

1 Answers1

0

Without looking too closely at your code, the issue seems to be coming from the way in which you are populating squares.

square = [0,0,0,0,0,0,0,0,0]
squares = []

def allsquares():
    for i in range(9):
        squares.append(square)
    return squares

allsquares appends list-references to the square list. These are not independent deep-copies of your square list, but just views to the same underlying list in memory. Any change you make to ANY of your list-references will result in the same change in all other "lists" - since all you're really doing is modifying the single underlying list.

Get rid of allsquares and square, and initialize squares using a list-comprehension:

squares = [[0] * 9 for _ in range(9)]

This will result in nine independent lists. That being said, this will allow the while-loop to terminate, however, I don't know if this actually results in your desired behavior.

Paul M.
  • 10,481
  • 2
  • 9
  • 15