By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,275 Members | 1,745 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,275 IT Pros & Developers. It's quick & easy.

help with addition of dictionary values

P: 10
hi,

i would like to add my two matrices, using __add__


Expand|Select|Wrap|Line Numbers
  1. class m:
  2.  
  3.     def __init__(self, mtx={}, m=0, n=0):
  4.         self.matrix = {}
  5.         self.matrix.update(mtx)
  6.         self.row = m
  7.         self.col = n
  8.  
  9.     def __getitem__(self, ij):
  10.         return self.matrix.get(ij,0)
  11.  
  12.     def __setitem__(self, ij, val):
  13.         self.matrix[i,j] = val
  14.  
  15.     def __add__(self, other):
  16.         result = m()
  17.         for i in other:
  18.             self.result[i] = self.matrix.get(i, 0) + other[i]
  19.         return result         
  20.  
but i always get an error.

Hope you can help me
Nov 10 '07 #1
Share this Question
Share on Google+
18 Replies


bartonc
Expert 5K+
P: 6,596
Use the dictionary method, items(). Like this:
Expand|Select|Wrap|Line Numbers
  1. >>> dd_1 = {'a':1, 'b':2, 'c':3}
  2. >>> dd_2 = {'a':3, 'b':4}
  3. >>> dd_res = {}
  4. >>> for key, value in dd_1.items():
  5. ...     dd_res[key] = dd_2.get(key, 0) + value
  6. ...     
  7. >>> dd_res
  8. {'a': 4, 'c': 3, 'b': 6}
  9. >>> 
Nov 10 '07 #2

P: 10
Use the dictionary method, items. Like this:
Expand|Select|Wrap|Line Numbers
  1. >>> dd_1 = {'a':1, 'b':2, 'c':3}
  2. >>> dd_2 = {'a':3, 'b':4}
  3. >>> dd_res = {}
  4. >>> for key, value in dd_1.items():
  5. ...     dd_res[key] = dd_2.get(key, 0) + value
  6. ...     
  7. >>> dd_res
  8. {'a': 4, 'c': 3, 'b': 6}
  9. >>> 
for this loop what does value means here? how can i use the one that i have set in __setitem__? does get(key, 0) gives me the value that i have set in __setitem__?

sorry if i sound confusing, but honestly i'm confused with the passing of tuples, i want to know exactly where does each value goes after using the method. am already fine with __init__ method, i'm just confused what happens to the values after setting them

for key, value in dd_1.items():
... dd_res[key] = dd_2.get(key, 0) + value
Nov 10 '07 #3

bartonc
Expert 5K+
P: 6,596
for this loop what does value means here? how can i use the one that i have set in __setitem__? does get(key, 0) gives me the value that i have set in __setitem__?

sorry if i sound confusing, but honestly i'm confused with the passing of tuples, i want to know exactly where does each value goes after using the method. am already fine with __init__ method, i'm just confused what happens to the values after setting them

for key, value in dd_1.items():
... dd_res[key] = dd_2.get(key, 0) + value
OK. Your class is coming along nicely. The on-line help can probably explain these things better that I can (more succinctly, anyway):
Expand|Select|Wrap|Line Numbers
  1. >>> help(dd_1.get)
  2. Help on built-in function get:
  3.  
  4. get(...)
  5.     D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
  6.  
  7. >>> help(dd_1.items)
  8. Help on built-in function items:
  9.  
  10. items(...)
  11.     D.items() -> list of D's (key, value) pairs, as 2-tuples
But probably the best way to learn what a chunk of code (your own or someone else's) is like this:
Expand|Select|Wrap|Line Numbers
  1. >>> for key, value in dd_1.items():
  2. ...     print key, value
  3. ...     dd_res[key] = dd_2.get(key, 0) + value
Nov 10 '07 #4

bartonc
Expert 5K+
P: 6,596
If the assignment doesn't allow using a subclass, you'll have to use the tricks below to take this apart and create your own class:
Expand|Select|Wrap|Line Numbers
  1. ...             
  2. >>> class sm(dict):
  3. ...     def __add__(self, other):
  4. ...         res = sm()
  5. ...         for key, value in other.items():
  6. ...             mine = self.get(key, 0)
  7. ...             res[key] = mine + value
  8. ...         return res
  9. ...     
  10. >>> sm_1 = sm({(0,0):5, (0,1):2})
  11. >>> sm_2 = sm({(0,0):7, (0,1):1})
  12. >>> sm_1 + sm_2
  13. {(0, 1): 3, (0, 0): 12}
  14. >>> 
You'll also need to add some additional logic to account for keys in sm_1 that don't exist in sm_2.
Nov 10 '07 #5

P: 10
hi,

before i start asking questions again, i really would like to thank this forum, slowly I was able to form my program, (especially bartonc and bvdet for wasting their time reading my pathetic questions lol), im really glad that someone is helping me...

back to my questions...

i tried to use the items() but i have error saying:
Expand|Select|Wrap|Line Numbers
  1. line 17, in __add__
  2.     for key, value in self.items():
  3. AttributeError: GeneralSparse instance has no attribute 'items'
items() is another function right? but can't i just utilize my __setitem__ and __getitem__, because my __setitem__ already sets the value of my matrix (please correct me if i'm wrong), so because i have set
Expand|Select|Wrap|Line Numbers
  1. self.matrix[ij] = val
on my __setitem__ the value know of my self.matrix is equal to val...

i tried to look back on my __str__ method, and tried to pattern some idea then end up with this:

Expand|Select|Wrap|Line Numbers
  1.     def __add__(self, other):
  2.         matrix = m() //i wrote it like this because it will implement my m class
  3.         for i in range(self.row):// i like my code to check the row one by one 
  4.             for j in range(self.col)://before jumping to the next row it has to check first each column that my row has and get the value of it
  5.                 self.matrix[i,j] = self[(i,j),0] + other[i,j]
  6.  
this one didn't give me any error but it also didn't give me anythng, the output is like this:
Expand|Select|Wrap|Line Numbers
  1. [0  0  0  0  0  0  0  
  2.  0  0  0  0  0  0  0  
  3.  0  5  0  0  0  0  0  
  4.  0  0  4  0  0  0  0  
  5.  0  0  0  0  0  0  0  
  6.  0  0  0  0  0  0  0  
  7.  0  0  0  0  0  0  0  ]
  8.  
  9. [0  0  0  0  0  0  0  
  10.  0  0  0  0  0  0  0  
  11.  0  8  0  0  0  0  0  
  12.  0  0  1  0  0  0  0  
  13.  0  0  0  0  0  0  0  
  14.  0  0  0  0  0  0  0  
  15.  0  0  0  0  0  0  0  ]
  16.  
  17. None
i don't understand why it is giving me "NONE"

then i tried this one also:
Expand|Select|Wrap|Line Numbers
  1. self.matrix[i,j] = self[.get(i,j),0] + other[i,j]
python gave me this error:
Expand|Select|Wrap|Line Numbers
  1. line 19, in __add__
  2.     self.matrix[i,j] = self.get[(i,j),0] + other[i,j]
  3. AttributeError: GeneralSparse instance has no attribute 'get'
i don't know how to interpret the errors python's throwing me..hope you can help me how to figure it out
Nov 10 '07 #6

bartonc
Expert 5K+
P: 6,596
hi,

i would like to add my two matrices, using __add__


Expand|Select|Wrap|Line Numbers
  1. class m:
  2.  
  3.     def __init__(self, mtx={}, m=0, n=0):
  4.         self.matrix = {}
  5.         self.matrix.update(mtx)
  6.         self.row = m
  7.         self.col = n
  8.  
  9.     def __getitem__(self, ij):
  10.         return self.matrix.get(ij,0)
  11.  
  12.     def __setitem__(self, ij, val):
  13.         self.matrix[i,j] = val
  14.  
  15.     def __add__(self, other):
  16.         result = m()
  17.         for i in other:
  18.             self.result[i] = self.matrix.get(i, 0) + other[i]
  19.         return result         
  20.  
but i always get an error.

Hope you can help me
Expand|Select|Wrap|Line Numbers
  1. # don't forget that you may want to use print statements with your object
  2.     def __repr__(self):
  3.         return str(self.matrix)
  4.  
  5.     def __getitem__(self, ij): # this is the syntax for calling with a tuple
  6.         return self.matrix.get(ij, 0)
  7.  
  8.     def __setitem__(self, ij, val):
  9.         self.matrix[ij] = val  # your version lacked consistance
  10.  
  11. sm_1 = sm({(0,0):5, (0,1):2})
  12. sm_1[(0,2)] = 8
  13. print sm_1
  14. print sm_1[(0,2)]
Nov 10 '07 #7

P: 10
Expand|Select|Wrap|Line Numbers
  1. # don't forget that you may want to use print statements with your object
  2.     def __repr__(self):
  3.         return str(self.matrix)
  4.  
  5.     def __getitem__(self, ij): # this is the syntax for calling with a tuple
  6.         return self.matrix.get(ij, 0)
  7.  
  8.     def __setitem__(self, ij, val):
  9.         self.matrix[ij] = val  # your version lacked consistance
  10.  
  11. sm_1 = sm({(0,0):5, (0,1):2})
  12. sm_1[(0,2)] = 8
  13. print sm_1
  14. print sm_1[(0,2)]
Expand|Select|Wrap|Line Numbers
  1.     def __getitem__(self, ij): # this is the syntax for calling with a tuple
  2.         return self.matrix.get(ij, 0)
  3.  
  4.     def __setitem__(self, ij, val):
  5.         self.matrix[ij] = val  # your version lacked consistance
what do you mean my version lacked consistence? do i need to add something? because what i understand about getitem and setitem is:

1. __getitem__ will get the index, if the dictionary that have been passed has no tuple it will assign 0 value but if it has then it will get the index or call the tuple

2. __setitem__ will take the index that __getitem__ got and assigned the value that the tuples has.

**please correct me if I am wrong**

Expand|Select|Wrap|Line Numbers
  1. # don't forget that you may want to use print statements with your object
this is my __str__()


Expand|Select|Wrap|Line Numbers
  1.     def __str__(self):
  2.         s = "["
  3.         if self.row > 0:
  4.             for i in range(self.row):
  5.                 for j in range(self.col):
  6.                     s += str(self[i,j])
  7.                     s += "  "
  8.                 if i < self.row-1:
  9.                     s += "\n "
  10.             s += "]\n"
  11.             return s
isn't it that __str__() does the job in printing my code? because, for this program all we have to do is to complete the methods (__init__, __getitem__, __setitem__, __add__, __mul__, __str__)

thanks
Nov 11 '07 #8

bartonc
Expert 5K+
P: 6,596
isn't it that __str__() does the job in printing my code?
Yes. That's correct. If there is not __str__(), then __repr__() gets called, though. It means "representation".
Nov 11 '07 #9

bartonc
Expert 5K+
P: 6,596
what do you mean my version lacked consistence?
Yours had a comma between i & j. There is no comma in mine (which I tested).
Nov 11 '07 #10

bartonc
Expert 5K+
P: 6,596
this is my __str__()
Very nice .
Nov 11 '07 #11

P: 10
this is my whole program
Expand|Select|Wrap|Line Numbers
  1. class GeneralSparse:
  2.  
  3.     def __init__(self, mtx={}, m=0, n=0):
  4.         self.matrix = {}
  5.         self.matrix.update(mtx)
  6.         self.row = m
  7.         self.col = n
  8.  
  9.     def __getitem__(self, ij):
  10.         return self.matrix.get(ij,0)
  11.  
  12.     def __setitem__(self, ij, val):
  13.         self.matrix[ij] = val
  14.  
  15.     def __add__(self, other):
  16.         matrix = GeneralSparse()
  17.         for i in range(self.row):
  18.             for j in range(self.col):
  19.                 self.matrix[i,j] = self[(i,j),0] + other[i,j]     
  20.  
  21.     def __str__(self):
  22.         s = "["
  23.         if self.row > 0:
  24.             for i in range(self.row):
  25.                 for j in range(self.col):
  26.                     s += str(self[i,j])
  27.                     s += "  "
  28.                 if i < self.row-1:
  29.                     s += "\n "
  30.             s += "]\n"
  31.             return s
  32.  
  33.  
  34. if __name__=="__main__":
  35.     x = GeneralSparse({(3,2):4, (2,1):5}, 7, 7)
  36.     y = GeneralSparse({(3,2):1, (2,1):8}, 7, 7)
  37.     print x
  38.     print y
  39.     a = x + y
  40.     print a
so far everything works pretty fine. it displays my two matrices but doesn't add them up, and gives me "NONE"

i can't still seem to figure out what's wrong or missing in my __add__(). and why it doesn't work

[
Nov 11 '07 #12

bartonc
Expert 5K+
P: 6,596
this is my whole program
Expand|Select|Wrap|Line Numbers
  1. class GeneralSparse:
  2.  
  3.     def __init__(self, mtx={}, m=0, n=0):
  4.         self.matrix = {}
  5.         self.matrix.update(mtx)
  6.         self.row = m
  7.         self.col = n
  8.  
  9.     def __getitem__(self, ij):
  10.         return self.matrix.get(ij,0)
  11.  
  12.     def __setitem__(self, ij, val):
  13.         self.matrix[ij] = val
  14.  
  15.     def __add__(self, other):
  16.         matrix = GeneralSparse()
  17.         for i in range(self.row):
  18.             for j in range(self.col):
  19.                 self.matrix[i,j] = self[(i,j),0] + other[i,j]     
  20.  
  21.     def __str__(self):
  22.         s = "["
  23.         if self.row > 0:
  24.             for i in range(self.row):
  25.                 for j in range(self.col):
  26.                     s += str(self[i,j])
  27.                     s += "  "
  28.                 if i < self.row-1:
  29.                     s += "\n "
  30.             s += "]\n"
  31.             return s
  32.  
  33.  
  34. if __name__=="__main__":
  35.     x = GeneralSparse({(3,2):4, (2,1):5}, 7, 7)
  36.     y = GeneralSparse({(3,2):1, (2,1):8}, 7, 7)
  37.     print x
  38.     print y
  39.     a = x + y
  40.     print a
so far everything works pretty fine. it displays my two matrices but doesn't add them up, and gives me "NONE"

i can't still seem to figure out what's wrong or missing in my __add__(). and why it doesn't work

[
You get None because you don't return a result. I've crafted an __add__() that may do more than you need, but you may learn a lot from these techniques:
Expand|Select|Wrap|Line Numbers
  1. #.....
  2.     def __add__(self, other):
  3.         res = sm({}, self.row, self.col)
  4.         for i in range(self.row):
  5.             for j in range(self.col):
  6.                 try: # does the left hand matrix have this element?
  7.                     mine = self.matrix[(i, j)]
  8.                     # Yes. try to get() from other or use zero
  9.                     res.matrix[(i, j)] = mine + other.matrix.get((i, j), 0)
  10.                 except KeyError: # No, does the right hand one?
  11.                     try:
  12.                         # yes. add it to the resulting matrix
  13.                         res.matrix[(i, j)] = other.matrix[(i, j)]
  14.                     except KeyError: # No
  15.                         pass # do nothing
  16.         return res
  17.  
  18. sm_1 = sm({(3,2):4, (2,1):5}, 7, 7)
  19. sm_2 = sm({(3,2):1, (2,1):8}, 7, 7)
  20. smSum = sm_1 + sm_2
  21. print smSum
  22. # this is from my repr() method
  23. {(3, 2): 5, (2, 1): 13}
Not that =python only go in the opening CODE tag. Thanks for paying attention to the post that you have seen in this regard.
Nov 11 '07 #13

bartonc
Expert 5K+
P: 6,596
You get None because you don't return a result. I've crafted an __add__() that may do more than you need, but you may learn a lot from these techniques:
Expand|Select|Wrap|Line Numbers
  1. #.....
  2.     def __add__(self, other):
  3.         res = sm({}, self.row, self.col)
  4.         for i in range(self.row):
  5.             for j in range(self.col):
  6.                 try: # does the left hand matrix have this element?
  7.                     mine = self.matrix[(i, j)]
  8.                     # Yes. try to get() from other or use zero
  9.                     res.matrix[(i, j)] = mine + other.matrix.get((i, j), 0)
  10.                 except KeyError: # No, does the right hand one?
  11.                     try:
  12.                         # yes. add it to the resulting matrix
  13.                         res.matrix[(i, j)] = other.matrix[(i, j)]
  14.                     except KeyError: # No
  15.                         pass # do nothing
  16.         return res
  17.  
  18. sm_1 = sm({(3,2):4, (2,1):5}, 7, 7)
  19. sm_2 = sm({(3,2):1, (2,1):8}, 7, 7)
  20. smSum = sm_1 + sm_2
  21. print smSum
  22. # this is from my repr() method
  23. {(3, 2): 5, (2, 1): 13}
Not that =python only go in the opening CODE tag. Thanks for paying attention to the post that you have seen in this regard.
Here are some mods:
Expand|Select|Wrap|Line Numbers
  1. #
  2.     def __getitem__(self, ij):
  3.         # Use self.matrix.get() if you really want zero for non-existent elements
  4.         return self.matrix[ij]
  5.         # If you don't use self.matrix.get() then you can eliminate matrix below (mostly)
  6.         # as shown here:
  7.  
  8.     def __add__(self, other):
  9.         res = sm({}, self.row, self.col)
  10.         for i in range(self.row):
  11.             for j in range(self.col):
  12.                 try: # does the left hand matrix have this element?
  13.                     mine = self[(i, j)]
  14.                     # Yes. try to get() from other or use zero
  15.                     res[(i, j)] = mine + other.matrix.get((i, j), 0) # using a subclass avoids the .matrix
  16.                 except KeyError: # No, does the right hand one?
  17.                     try:
  18.                         # yes. add it to the resulting matrix
  19.                         res[(i, j)] = other[(i, j)]
  20.                     except KeyError: # No
  21.                         pass # do nothing
  22.         return res
Nov 11 '07 #14

bartonc
Expert 5K+
P: 6,596
Here are some mods:
Expand|Select|Wrap|Line Numbers
  1. #
  2.     def __getitem__(self, ij):
  3.         # Use self.matrix.get() if you really want zero for non-existent elements
  4.         return self.matrix[ij]
  5.         # If you don't use self.matrix.get() then you can eliminate matrix below (mostly)
  6.         # as shown here:
  7.  
  8.     def __add__(self, other):
  9.         res = sm({}, self.row, self.col)
  10.         for i in range(self.row):
  11.             for j in range(self.col):
  12.                 try: # does the left hand matrix have this element?
  13.                     mine = self[(i, j)]
  14.                     # Yes. try to get() from other or use zero
  15.                     res[(i, j)] = mine + other.matrix.get((i, j), 0) # using a subclass avoids the .matrix
  16.                 except KeyError: # No, does the right hand one?
  17.                     try:
  18.                         # yes. add it to the resulting matrix
  19.                         res[(i, j)] = other[(i, j)]
  20.                     except KeyError: # No
  21.                         pass # do nothing
  22.         return res
And here it is as a subclass of built-in.dict using if and elif instead of nested try blocks:
Expand|Select|Wrap|Line Numbers
  1. class smd(dict): # a dictionary like object
  2.     def __init__(self, mtx={}, m=0, n=0):
  3.         self.update(mtx)
  4.         self.row = m
  5.         self.col = n
  6.  
  7.     def __add__(self, other):
  8.         res = smd({}, self.row, self.col)
  9.         for i in range(self.row):
  10.             for j in range(self.col):
  11.                 if (i, j) in self: # does the left hand matrix have this element?
  12.                     mine = self[(i, j)]
  13.                     # Yes. try to get() from other or use zero
  14.                     res[(i, j)] = mine + other.get((i, j), 0)
  15.                 elif (i, j) in other: # No, does the right hand one?
  16.                     # yes. add it to the resulting matrix
  17.                     res[(i, j)] = other[(i, j)]
  18.         return res
  19.  
  20.  
  21. sm_1 = smd({(3,2):4, (2,1):5, (2,2):6}, 7, 7)
  22. sm_2 = smd({(3,2):1, (2,1):8, (4,4):6}, 7, 7)
  23. smSum = sm_1 + sm_2
  24. print smSum
  25. # from dict.__str_()
  26. {(3, 2): 5, (4, 4): 6, (2, 1): 13, (2, 2): 6}
Nov 11 '07 #15

P: 10
hi bartonc,

i tried to follow the your code. i tried to use get() before but python keeps saying that my class has no attribute get, that's why I lose hope using it. thanks for showing me how...

i tried to follow your code and this is what i end up with
Expand|Select|Wrap|Line Numbers
  1.     def __add__(self, other):
  2.         result = GeneralSparse()
  3.         for i in range(self.row):
  4.             for j in range(self.col):
  5.                 if (i,j) in self:
  6.                     mtx = self[i,j]
  7.                     result[(i,j)] = mtx + other.matrix.get((i,j),0)
  8.                 elif (i,j) in other:
  9.                     result[(i,j)] = other[(i,j),0]
  10.         return result
can you please check if what's wrong with what i have done because python still complains it just gives back my two matrices and not even saying any error at all just this:
Expand|Select|Wrap|Line Numbers
  1. IDLE 1.2.1      
  2. >>> ================================ RESTART ================================
  3. >>> 
  4. [0  0  0  0  0  0  0   
  5.  0  0  0  0  0  0  0   
  6.  0  5  0  0  0  0  0   
  7.  0  0  4  0  0  0  0   
  8.  0  0  0  0  0  0  0   
  9.  0  0  0  0  0  0  0   
  10.  0  0  0  0  0  0  0  ]
  11.  
  12. [0  0  0  0  0  0  0   
  13.  0  0  0  0  0  0  0   
  14.  0  8  0  0  0  0  0   
  15.  0  0  1  0  0  0  0   
  16.  0  0  0  0  0  0  0   
  17.  0  0  0  0  0  0  0   
  18.  0  0  0  0  0  0  0  ]
  19.  
Nov 11 '07 #16

bartonc
Expert 5K+
P: 6,596
hi bartonc,

i tried to follow the your code. i tried to use get() before but python keeps saying that my class has no attribute get, that's why I lose hope using it. thanks for showing me how...

i tried to follow your code and this is what i end up with
Expand|Select|Wrap|Line Numbers
  1.     def __add__(self, other):
  2.         result = GeneralSparse()
  3.         for i in range(self.row):
  4.             for j in range(self.col):
  5.                 if (i,j) in self:
  6.                     mtx = self[i,j]
  7.                     result[(i,j)] = mtx + other.matrix.get((i,j),0)
  8.                 elif (i,j) in other:
  9.                     result[(i,j)] = other[(i,j),0]
  10.         return result
can you please check if what's wrong with what i have done because python still complains it just gives back my two matrices and not even saying any error at all just this:
Expand|Select|Wrap|Line Numbers
  1. IDLE 1.2.1      
  2. >>> ================================ RESTART ================================
  3. >>> 
  4. [0  0  0  0  0  0  0   
  5.  0  0  0  0  0  0  0   
  6.  0  5  0  0  0  0  0   
  7.  0  0  4  0  0  0  0   
  8.  0  0  0  0  0  0  0   
  9.  0  0  0  0  0  0  0   
  10.  0  0  0  0  0  0  0  ]
  11.  
  12. [0  0  0  0  0  0  0   
  13.  0  0  0  0  0  0  0   
  14.  0  8  0  0  0  0  0   
  15.  0  0  1  0  0  0  0   
  16.  0  0  0  0  0  0  0   
  17.  0  0  0  0  0  0  0   
  18.  0  0  0  0  0  0  0  ]
  19.  
Mine works because it is a subclass of bult-in.dict. To make yours work you can add:
Expand|Select|Wrap|Line Numbers
  1. # this:
  2.  
  3.     def get(self, key, default=None):
  4.         return self.matrix.get(key, default)
to your class. Or change references from self to self.matrix:
Expand|Select|Wrap|Line Numbers
  1.     def __add__(self, other):
  2.         result = GeneralSparse()
  3.         for i in range(self.row):
  4.             for j in range(self.col):
  5.                 if (i, j) in self.matrix:
  6.                     item = self[i,j]
  7.                     result[(i,j)] = item + other.matrix.get((i,j), 0)
  8.                 elif (i,j) in other.matrix:
  9.                     result[(i,j)] = other[(i,j)] # !No default in the getitem() syntax!
  10.         return result
Nov 11 '07 #17

bvdet
Expert Mod 2.5K+
P: 2,851
Mine works because it is a subclass of bult-in.dict. To make yours work you can add:
Expand|Select|Wrap|Line Numbers
  1. # this:
  2.  
  3.     def get(self, key, default=None):
  4.         return self.matrix.get(key, default)
to your class. Or change references from self to self.matrix:
Expand|Select|Wrap|Line Numbers
  1.     def __add__(self, other):
  2.         result = GeneralSparse()
  3.         for i in range(self.row):
  4.             for j in range(self.col):
  5.                 if (i, j) in self.matrix:
  6.                     item = self[i,j]
  7.                     result[(i,j)] = item + other.matrix.get((i,j), 0)
  8.                 elif (i,j) in other.matrix:
  9.                     result[(i,j)] = other[(i,j)] # !No default in the getitem() syntax!
  10.         return result
What if there are more rows and/or columns on 'other'? Will the new instance object have any rows or columns if none are assigned? GeneralSparse() __init__ method defaults to 0 rows and columns. I took a different but less elegant approach:
Expand|Select|Wrap|Line Numbers
  1. ....def __add__(self, other):
  2.         dd = {}
  3.         # add all keys found in self and other
  4.         keys = self.matrix.keys()
  5.         for key in keys:
  6.             dd[key] = self.matrix[key] + other.matrix.get(key, 0)
  7.         # add all keys found in other but not in self
  8.         keysOther = other.matrix.keys()
  9.         for key in keysOther:
  10.             if key not in keys:
  11.                 dd[key] = other.matrix[key]
  12.         return GeneralSparse(dd, max(self.row, other.row), max(self.col, other.col))
Interactive:
Expand|Select|Wrap|Line Numbers
  1. >>> z = GeneralSparse({(3,2):1, (2,1):8, (6,4):12}, 7, 7)
  2. >>> w = GeneralSparse({(1,2):1, (3,1):8, (6,4):12, (7,8):225.5}, 8, 9)
  3. >>> zw = z+w
  4. >>> print zw
  5. [0 0 0 0 0 0 0 0 0
  6. 0 0 1 0 0 0 0 0 0
  7. 0 8 0 0 0 0 0 0 0
  8. 0 8 1 0 0 0 0 0 0
  9. 0 0 0 0 0 0 0 0 0
  10. 0 0 0 0 0 0 0 0 0
  11. 0 0 0 0 24 0 0 0 0
  12. 0 0 0 0 0 0 0 0 225.5]
  13. >>> 
Here is another version that produces a slightly different resulting instance:
Expand|Select|Wrap|Line Numbers
  1. ....def __add__(self, other):
  2.         keys = []
  3.         for key in self.matrix.keys()+other.matrix.keys():
  4.             if key not in keys:
  5.                 keys.append(key)
  6.         dd = {}
  7.         for key in keys:
  8.             dd[key] = self.matrix.get(key,0)+other.matrix.get(key,0)
  9.         return GeneralSparse(dd, max([i[0] for i in keys])+1, max([j[1] for j in keys])+1)
The OP's __str__ method looked OK and seemed to work properly, but we can eliminate string concatenation by using the list method 'join()'. The following uses a list comprehension to accomplish this:
Expand|Select|Wrap|Line Numbers
  1. ....def __str__(self):
  2.         return '[%s]' % '\n'.join([' '.join([str(self[i,j]) for j in range(self.col)]) for i in range(self.row)])
The following does basically the same thing without a list comprehension:
Expand|Select|Wrap|Line Numbers
  1. ....def __str__(self):
  2.         res = []
  3.         for i in range(self.row):
  4.             seq = []
  5.             for j in range(self.col):
  6.                 seq.append(str(self[i,j]))
  7.             res.append(' '.join(seq))
  8.         return '[%s]' % '\n'.join(res)
Nov 12 '07 #18

bartonc
Expert 5K+
P: 6,596
Thanks for joining in, here, bvdet. Granted, you are far more experienced with these dictionary extensions that I am; I thought that maybe you were just keeping an eye out to see where I'd end up going with this one.

Also, please note that this is a coursework thread and I must encourage experts to keep full solutions to themselves (per site rules).
Nov 12 '07 #19

Post your reply

Sign in to post your reply or Sign up for a free account.