Program That Should Add A List To A Dictionary And Then Clear It, Clears It First And Appends The Subsequent Empty List To Dictionary?
Solution 1:
The problem is that you are using self.generalPurposeList
so self.rowStorer
is saving a reference to that object instead of the list you want. Later, you clear that object using self.generalPurposeList.clear()
, which is why you get an empty result.
change the line
self.rowStorer.setdefault(i+1,self.generalPurposeList)
to
self.rowStorer.setdefault(i+1,self.generalPurposeList.copy())
This adds a new list containing the values in the generalPurposeList
list, and clearing the old list will not affect this one.
Solution 2:
For starters, I don't recommend baking user interaction into the constructor. This unnecessarily limits reusability of the class. Move it to the caller and let them collect the input in a different module and provide it as an iterable to the matrix class.
I then clear this list after its added to the dictionary as a key, to clean it up and ready it for the next row's elements
Clearing the same row list over and over won't work because the dict references one instance of your list generalPurposeList
from every key as described in List of lists changes reflected across sublists unexpectedly. Clearing one reference clears them all. I'd expect you want to collect a row, append it to the list of rows and then create a new list for the next row.
There is no advantage to making generalPurposeList
an instance variable and this sort of premature optimization to avoid allocations is almost never done; that list should be in the narrowest scope needed, namely, inside the row for
loop. The bug/confusion seems to be a direct consequence of this design decision.
Using a dict to implement a matrix is an odd choice; I'd use a list which is the best data structure for sequences of buckets from 0-n.
I also recommend using the dunder method __repr__
rather than __str__
which is automatically invoked by print
. Either way, calling the dunder method directly is an antipattern; use str(foo)
rather than foo.__str__()
in most cases.
I suggest something like:
classMatrix:
def__init__(self, rows=[]):
self.rows = rows
def__repr__(self):
return"\n".join([str(x) for x in self.rows])
if __name__ == "__main__":
defcollect_int(
prompt,
err_msg="Invalid number entered. Please try again."):
whileTrue:
try:
returnint(input(prompt))
except ValueError:
print(err_msg)
mat = []
rows = collect_int("Enter the number of rows: ")
cols = collect_int("Enter the number of cols: ")
for i inrange(rows):
mat.append([])
for j inrange(cols):
mat[-1].append(collect_int(f"Enter A[{i}][{j}]: "))
print(Matrix(mat))
Sample run:
Enter the number of rows: 2
Enter the number of cols: 4
Enter A[0][0]: gergerg
Invalid number entered. Please try again.
Enter A[0][0]: 0
Enter A[0][1]: 1
Enter A[0][2]: 2
Enter A[0][3]: 3
Enter A[1][0]: 4
Enter A[1][1]: 5
Enter A[1][2]: 6
Enter A[1][3]: 7
[0, 1, 2, 3]
[4, 5, 6, 7]
If the matrix class seems slim, that's fine -- it's responsible for what it should be responsible for under your current design and nothing more. I assume you'd add more methods to it like transpose
, eye
, etc, so it'll be more meaningful than just a pretty printer for 2d lists as it is now.
BTW, I'm sure you're doing this for educational purposes, but NumPy already implements optimized matrices so keep in mind you'll likely never write a matrix class like this in a real app.
Lastly, note I implemented only rudimentary error checking. Your collect_int
function should probably accept a function predicate to prevent rows and columns from being negative numbers.
Post a Comment for "Program That Should Add A List To A Dictionary And Then Clear It, Clears It First And Appends The Subsequent Empty List To Dictionary?"