[Tutor] The Python way and two dimensional lists

Alan Gauld alan.gauld at yahoo.co.uk
Mon Nov 22 04:58:41 EST 2021


On 22/11/2021 06:02, Phil wrote:

> I now have this:
> 
> num_rows = 9
> num_cols = 9
> 
> solution = [[0 for i in range(num_cols)] for j in range(num_rows)]
> 
> # solution row column
> 
> solution[0][0] = {7,3}, {5}, {4,8,6}, {7,8}, {1}, {9,3}, {7,9}, {4,6,3}, 
> {2}

I think you actually wanted:

solution[0] = [{7,3}, {5}, {4,8,6}, {7,8}, {1}, {9,3}, {7,9}, {4,6,3},
{2}]

That initialised the first row to the list of sets.

What you have creates a tuple and inserts all of those sets into the
first cell. I'm fairly sure that's not what you meant to do.

> solution[0][1] = {1}
> solution[0][2] = {2}
> solution[0][3] = {3}
> solution[0][4] = {4}
> solution[0][5] = {5}
> solution[0][6] = {6}
> solution[0][7] = {7}
> solution[0][8] = {8}
> 
> So row 0 is {7,3}, {5} etc

No, your code made the first cell of row 0 contain all those
sets. The subsequent assignments filled the remaining cells
with 1-8 respectively.

> and row 1 is {1} followed by 8 zeros

No, you haven't put anything into row 1. So it is all
zeros (from the list comprehension).

One thing you might consider is using the Python
interactive prompt (>>>) to experiment before you
code to see what each value returns. The prompt is a
very useful tool when programming but for some reason
many programmers neglect to use it while writing code.

Another option that could work here, and is often
used in professional code, is to just do the initialisation
in a hard coded list format:

solution = [
[{7,3}, {5}, {4,8,6}, {7,8}, {1}, {9,3}, {7,9}, {4,6,3}, {2}],
[{1},0,0,0,0,0,0,0,0],
[{2},0,0,0,0,0,0,0,0],
[{3},0,0,0,0,0,0,0,0],
[{4},0,0,0,0,0,0,0,0],
[{5},0,0,0,0,0,0,0,0],
[{6},0,0,0,0,0,0,0,0],
[{7},0,0,0,0,0,0,0,0],
[{8},0,0,0,0,0,0,0,0]
]

You can then insert any other values you need into the
cells directly.

Obviously this technique isn't effective with huge data
sets, but for this purpose should work well and may help
you visualize things better.

Note that this duplicates what I think you were trying to do with your
assignments. Also note the discrepancy in data types between the zeros
you used in initialising the lists and the sets you use in your
assignments. Might it be better to initialize with empty sets
instead of 0s? (Empty sets are created with set())


> 
> for row in solution:
>      print(row[0])
> 
> ({3, 7}, {5}, {8, 4, 6}, {8, 7}, {1}, {9, 3}, {9, 7}, {3, 4, 6}, {2})
> 0
> 0
> 0
> 0
> 0
> 0
> 0
> 0
> 
> Why do the sets represent only one position and the eight zeros make up 
> the remaining nine positions?

Try creating 2D lists using values other than 0 in the >>> prompt:

test_table = [[c for c in 'abcdefgh'] for  n in range(9)]

Then try printing rows and columns using the prompt and
different indices until you feel comfortable extracting
what you need. You will learn a lot that way.

>> You can build a copy of a column easily enough with:
>>
>> col6 = [row[5] for row in solution]
> col0 = [row[0] for row in solution]
> 
> print('column ', col0)
> 
> prints row 0 with 8 extra zeros:
> 
> column  [({3, 7}, {5}, {8, 4, 6}, {8, 7}, {1}, {9, 3}, {9, 7}, {3, 4, 
> 6}, {2}), 0, 0, 0, 0, 0, 0, 0, 0]
> 
> It's those extra zeros again.

Hopefully the above explanation shows where they came from.
And the interactive session has clarified what you need to do?


> col0 = [row[6] for row in solution]
> print('column ', col0)
> 
> prints and this is what I did expect:
> 
> column  [{6}, 0, 0, 0, 0, 0, 0, 0, 0]

really? It's not what I would expect!

> 
>> But if you change any values you need to regenerate
>> the copy so it's not exactly efficient.
> 
> Is there a Python way to access any point on the grid with something 
> like x = row[6][col7]. This is how I had originally accessed the grid. 

Yes that's exactly what you can do using 2 indices.
What you can't do is access whole columns.

> I'm happy to change the entire design so that I have a static grid that 
> I can access with a row, col combination. Having to build a column every 
> time I want to access it seems like a lot of unnecessary extra effort. 
> Should I investigate the array module rather that persisting with lists? 
> Arrays make more sense to me.

There is very little difference in python between arrays and lists.
But lists are such a flexible and all pervasive data structure in
Python that you really should stick with them. They are a fundamental
skill for every Python user.

Just remember that row and column are solution concepts that
Python does not understand. All python knows is that a list
is a sequence of values that can be accessed using an index.
Those values may or may not be other lists.

In a 2D list structure the top level list does not know that the
sublists are lists. To it they are just value objects like
any other. It certainly doesn't know that they represent a
table with rows and columns. That concept resides solely
in the programmer's(ie. your) head.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list