1

I'm working on a sudoku solver and I have this board:

board = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
]

And let's say I now want to just change every number to a random one (between 1 and 9). I tried this:

for lst in board:
    for num in lst:
        num = random.randint(1, 9)

I think this just takes the zeros and changes them to the random numbers but doesn't write them back into the list, because when I print the list it's still just zeroes. So how do I make it to actually write the random numbers back into the board?

Sorry for the basic question, I'm new. I tried looking it up but I just don't seem to understand for loops correctly...

2

6 Answers 6

1

You are assigning to a new variable (named num just as your for variable). For your task you need to have indices.

The most straightforward solution using range(len(x)):

for row in board: # can iterate over indices here too, but it's unnececssary
    for index in range(len(row)):
        row[index] = random.randint(1, 9)

Better approach could be used. To generate a new list with random numbers you can use list comprehensions:

# using '_' as variable since it's unused
board = [
    [random.randint(1, 9) for _ in range(9)] # row itself
    for _ in range(9) # iterating over rows
]
Sign up to request clarification or add additional context in comments.

1 Comment

There may be a problem using the underscore _ in two nested loops. It's a common placeholder but usually only used for one purpose in a given statement. Otherwise, good answers.
1

Try this

for i, lst in enumerate(board):
    for j, num in enumerate(lst):
        board[i][j] = random.randint(1, 9)

I'll leave it as an exercise to understand why that solves the problem of assigning numbers to lists (though not that of assigning each of the numbers exactly 9 times)

Comments

0
for lst in range(len(board)):

    for num in range(len(board[lst])):

        board[lst][num] = random.randint(1, 9)

1 Comment

Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
0

Quite shorter method is:

board = [random.sample(range(1,10), 9) for _ in board]

Comments

0

You are changing num to the random number, not the actual list. For that, you need to do:

for i in range(len(board)):
    for j in range(len(board[i])):
        board[i][j] = random.randint(1, 9)

For simplicity, I will use a non-nested loop. Basically, you are iterating board, you are setting lst = board[current_iteration]. In it's while loop form:

#This is just to make my point clear, don't use this, for loops are better most of the times
while i < len(board):
    lst = board[i] #You are setting lst to board[i], then changing lst instead of board[i]
    lst = #Whatever you like
    i += 1

lst is not connected to board[i], so changing lst won't change board. The thing you are wanting is connected variables, which is possible with lists or objects in Pyhton but are not recommended due to low speed and complex nature. But you could use C pointers pretty easily and build a weird C pointer wrapper for that.

Numpy solution:

board = np.random.randint(low=1, high=10, size=[10, 10]) #Don't know how big sudoku board is, assume it's 10 * 10.

5 Comments

Interesting solution with the while loop, is there any advantage in using it instead of the nested for loop? I mean is there a way to know which of these two approches is faster/better?
@Vojta I only used the while loop to show what happens behind the scenes when for loop is used. A while loop is generally faster but you can't use range() with while loops, and range() is the only thing in Python ever to shock me with its speed. It's very fast, so overall, because you can use range() with for loops, they are faster.
@Vojta As you have a 2D array, you still need a nested while loop. You better use numpy for these type of stuff.
I'm sure numpy would do a better job, but I'm still at the stage where I'm learning to understand the basic Python functions. Your reply helped a lot, thanks!
@Vojta Don't worry, Numpy doesn't need mastering anything. I would recommend you occasionally use some basic numpy functions for shortcuts but don't use it too much because the shortcuts will prevent you from practicing. Even if you have no intentions of using numpy, it must be on your machine, it's an extremely important library, the most important library to be exact.
0

You are not changing the board inplace.

for i in range(len(board)):
    for j in range(len(board[i])):
        board[i][j] = random.randint(1, 9)

You can also create board with numpy.random.randint() which generates values between [low, high), ff high is None (the default), then results are from [0, low).

import numpy as np
print(np.random.randint(low=1, high=10, size=(9,9)))

"""
[[4 7 3 4 8 9 8 7 1]
 [8 7 1 3 2 8 8 3 2]
 [4 8 5 9 8 8 9 1 3]
 [5 4 8 5 5 9 3 3 6]
 [7 7 4 7 8 7 2 5 1]
 [7 9 8 1 2 6 5 7 3]
 [9 3 4 1 6 3 2 9 3]
 [7 3 5 7 7 1 3 4 3]
 [7 4 3 5 3 8 8 8 6]]
"""

1 Comment

A high=9 will not give the value 9 anywhere, it needs to be high=10.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.