[Tutor] Creating a two dimension set
Cameron Simpson
cs at cskk.id.au
Sun Oct 31 16:08:08 EDT 2021
On 31Oct2021 15:56, Phil <phillor9 at gmail.com> wrote:
>As an example, if I wanted to create a two dimension list I would write:
>
>num_rows = 9
>num_cols = 9
>
>self.solution = [[None] * num_cols for _ in range(num_rows)]
Keeping in mind that this is a list of lists. Also, you're preallocating
num_cols*nul_rows of storage. That can be wasteful if you're not filling
much of it in.
>In my current creation I need a two dimension set and so I have used,
>again for example:
>
>result = set(self.solution[row][col]) - 3
This line makes no sense to me: you cannot subtract a number from a set.
And initialising a set requires an iterable - does your list-of-lists
itself contain lists? The "None" in your first example suggests maybe
not.
>However, my code has grown and I find that I'm making mistakes and it
>would be much simpler if I'd created a two dimension set in the first
>place rather that converting the list to a set every time I need to
>access it.
>
>I could, I suppose, use two for loops to create and initialise the set
>but there must be a simpler and less tedious way.
I do not fully understand your use case, partly because your second
example is not sane Python.
I'm also not sure you mean "set". Can you tell us in more detail what
you're doing, maybe a very small example programme?
Might I suggest a dict indexed by a 2-tuple of (row,col)?
A dict maps keys to values. If your keys are coordinate pairs you can
use this mapping like a 2-dimensional array. Example:
d = {}
d[1, 2] = 9 # store 9 at (1,2)
d[3, 5] = 10 # store 10 at (3,5)
There are 2 caveats here:
Dict keys must be static hashable values. ints, float, strings fit this
bill. So do tuples of such values, eg (1,2).
The other issue is what to do with the coordinates you have not set. For
example, what happens if you access d[2,2] in the above code? There is
no (2,2) entry, and a dict will raise a KeyError exception.
You have 2 main approaches to this: a defaultdict (presupplied in the
standard library) or a dict subclass with a __missing__ method. The
former will fill in entries as you access them - this is easy and
convenient and I suggest you use it first. The latter need not fill in
entries, but is more work to implement.
Using a defaultdict is like this:
from collections import defaultdict
.......
d = defaultdict(int)
d[1, 2] = 9 # store 9 at (1,2)
d[3, 5] = 10 # store 10 at (3,5)
This is as before, but accessing an unfilled entry will fill it with the
result of calling int(), which makes a 0. You can give defaultdict any
callable which requires not arguments. For example "float", the float
type, which will return 0.0 from floatz(). Or a small lambda if you want
"None":
d = defaultdict(lambda: None)
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Tutor
mailing list