Problems with dictionaries

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Oct 2009
Posts: 18
Reputation: pyprog is an unknown quantity at this point 
Solved Threads: 0
pyprog pyprog is offline Offline
Newbie Poster

Problems with dictionaries

 
0
  #1
Nov 8th, 2009
Assume I have a file of the following format:
a,1
b,2
c,3
d,4
Here is my code:
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return (d1, d2)
  11.  
  12.  
  13. def something():
  14. print d1
  15. print d2
  16.  
  17. if __name__ == "__main__":
  18. f = open("filename.txt")
  19. d1 = junk(f)[0]
  20. d2 = junk(f)[1]

Assume I want to call function something. It cannot print d1 and d2 unless I add them to the main block. As soon as I add d1 and d2 to the "main" block and call either of the two functions, both return two empty dictionaries. Why does this happen? How can I fix it? Please help!
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 1,074
Reputation: woooee is a jewel in the rough woooee is a jewel in the rough woooee is a jewel in the rough 
Solved Threads: 299
woooee woooee is offline Offline
Veteran Poster
 
0
  #2
Nov 8th, 2009
First you are not returning a dictionary. I've added a print statement to show that. Also, take a look at "returns" and "arguments" here http://www.penzilla.net/tutorials/python/functions/ for the "something" function.
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return (d1, d2)
  11.  
  12.  
  13. def something():
  14. print d1
  15. print d2
  16.  
  17. if __name__ == "__main__":
  18. f = open("filename.txt")
  19. d1 = junk(f)[0]
  20. print "type d1 =", type(d1)
  21. d2 = junk(f)[1]
Last edited by woooee; Nov 8th, 2009 at 1:19 pm.
Linux counter #99383
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 18
Reputation: pyprog is an unknown quantity at this point 
Solved Threads: 0
pyprog pyprog is offline Offline
Newbie Poster
 
0
  #3
Nov 8th, 2009
Originally Posted by woooee View Post
First you are not returning a dictionary. I've added a print statement to show that. Also, take a look at "returns" and "arguments" here http://www.penzilla.net/tutorials/python/functions/ for the "something" function.
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return (d1, d2)
  11.  
  12.  
  13. def something():
  14. print d1
  15. print d2
  16.  
  17. if __name__ == "__main__":
  18. f = open("filename.txt")
  19. d1 = junk(f)[0]
  20. print "type d1 =", type(d1)
  21. d2 = junk(f)[1]
I still don't get it. The type of d1 is dictionary.
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 1,074
Reputation: woooee is a jewel in the rough woooee is a jewel in the rough woooee is a jewel in the rough 
Solved Threads: 299
woooee woooee is offline Offline
Veteran Poster
 
0
  #4
Nov 8th, 2009
Try this and then go to the page from the earlier link which explains why you returned a tuple.
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return d1, d2
  11.  
  12. if __name__ == "__main__":
  13. f = open("filename.txt")
  14. d1_ret, d2_ret = junk(f)[0]
  15. print type(d1_ret)
Linux counter #99383
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 18
Reputation: pyprog is an unknown quantity at this point 
Solved Threads: 0
pyprog pyprog is offline Offline
Newbie Poster
 
0
  #5
Nov 8th, 2009
Originally Posted by woooee View Post
Try this and then go to the page from the earlier link which explains why you returned a tuple.
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return d1, d2
  11.  
  12. if __name__ == "__main__":
  13. f = open("filename.txt")
  14. d1_ret, d2_ret = junk(f)[0]
  15. print type(d1_ret)
OK, I see that putting a comma between two variables automatically returns a tuple. But the problem is that as long as d1(d1_ret) or d2(d2_ret) in the "main" block junk(f) would return twoempty dictionaries in a tuple. That is what I don't understand.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,151
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 952
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite
 
0
  #6
Nov 8th, 2009
Originally Posted by pyprog View Post
Assume I have a file of the following format:
a,1
b,2
c,3
d,4
Here is my code:
  1. def junk(f):
  2. d1 = {}
  3. d2 = {}
  4. for line in f:
  5. columns = line.split(":")
  6. letters = columns[1]
  7. numbers = columns[2]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return (d1, d2)
  11.  
  12.  
  13. def something():
  14. print d1
  15. print d2
  16.  
  17. if __name__ == "__main__":
  18. f = open("filename.txt")
  19. d1 = junk(f)[0]
  20. d2 = junk(f)[1]

Assume I want to call function something. It cannot print d1 and d2 unless I add them to the main block. As soon as I add d1 and d2 to the "main" block and call either of the two functions, both return two empty dictionaries. Why does this happen? How can I fix it? Please help!
Really just a series of somewhat careless beginner mistakes you can fix this way ...
  1. """assume file "filename.txt" has this content
  2. a,1
  3. b,2
  4. c,3
  5. d,4
  6. """
  7.  
  8. def junk(f):
  9. d1 = {}
  10. d2 = {}
  11. for line in f:
  12. columns = line.split(",") # <---- delimiter is comma
  13. letters = columns[0] # <---- index starts with 0
  14. numbers = columns[1] # <---- index again
  15. d1[letters] = numbers
  16. d2[numbers] = letters
  17. return d1, d2
  18.  
  19. def something(d1, d2): # <---- give function proper arguments
  20. print d1
  21. print d2
  22.  
  23. if __name__ == "__main__":
  24. f = open("filename.txt")
  25. d1, d2 = junk(f) # expand the tuple that is returned
  26. something(d1, d2) # give function its needed arguments
  27.  
  28. """my output -->
  29. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  30. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  31. """
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 18
Reputation: pyprog is an unknown quantity at this point 
Solved Threads: 0
pyprog pyprog is offline Offline
Newbie Poster
 
0
  #7
Nov 8th, 2009
Originally Posted by vegaseat View Post
Really just a series of somewhat careless beginner mistakes you can fix this way ...
  1. """assume file "filename.txt" has this content
  2. a,1
  3. b,2
  4. c,3
  5. d,4
  6. """
  7.  
  8. def junk(f):
  9. d1 = {}
  10. d2 = {}
  11. for line in f:
  12. columns = line.split(",") # <---- delimiter is comma
  13. letters = columns[0] # <---- index starts with 0
  14. numbers = columns[1] # <---- index again
  15. d1[letters] = numbers
  16. d2[numbers] = letters
  17. return d1, d2
  18.  
  19. def something(d1, d2): # <---- give function proper arguments
  20. print d1
  21. print d2
  22.  
  23. if __name__ == "__main__":
  24. f = open("filename.txt")
  25. d1, d2 = junk(f) # expand the tuple that is returned
  26. something(d1, d2) # give function its needed arguments
  27.  
  28. """my output -->
  29. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  30. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  31. """
But how come if you call the function junk again after the program finished executing and showed the output, it will return two empty dicts?
Last edited by pyprog; Nov 8th, 2009 at 3:28 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,151
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 952
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite
 
0
  #8
Nov 8th, 2009
Originally Posted by pyprog View Post
But how come if you call the function junk again after the program finished executing and showed the output, it will return two empty dicts?
Because the code is also poorly designed, ideally you should send the file name to the function, open the file there, read and close it.

You can fix your code this way ...
  1. def junk(fh):
  2. d1 = {}
  3. d2 = {}
  4. for line in fh:
  5. columns = line.split(",")
  6. letters = columns[0]
  7. numbers = columns[1]
  8. d1[letters] = numbers
  9. d2[numbers] = letters
  10. return d1, d2
  11.  
  12. def something(d1, d2):
  13. print d1
  14. print d2
  15.  
  16. if __name__ == "__main__":
  17. fh = open("filename.txt")
  18. d1, d2 = junk(fh)
  19. something(d1, d2)
  20. print( '-'*50 )
  21. # second time around
  22. # file handle fh is at the end of the file now
  23. # reset it to the start of the file
  24. fh.seek(0)
  25. d1, d2 = junk(fh)
  26. something(d1, d2)
  27.  
  28. """my output -->
  29. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  30. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  31. --------------------------------------------------
  32. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  33. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  34. """
This would have been the better design ...
  1. """assume file "filename.txt" has this content
  2. a,1
  3. b,2
  4. c,3
  5. d,4
  6. """
  7.  
  8. def file2dictionary(fname):
  9. """
  10. read data from file and create a dictionary d1 and its reverse d2
  11. """
  12. fh = open("filename.txt")
  13. d1 = {}
  14. d2 = {}
  15. for line in fh:
  16. columns = line.split(",")
  17. letters = columns[0]
  18. numbers = columns[1]
  19. d1[letters] = numbers
  20. d2[numbers] = letters
  21. fh.close()
  22. return d1, d2
  23.  
  24. def print_dict(d1, d2):
  25. """print the two dictionaries d1 and d2"""
  26. print(d1)
  27. print(d2)
  28.  
  29. if __name__ == "__main__":
  30. fname = "filename.txt"
  31. d1, d2 = file2dictionary(fname)
  32. print_dict(d1, d2)
  33. print( '-'*50 )
  34. # test second time around
  35. d1, d2 = file2dictionary(fname)
  36. print_dict(d1, d2)
  37.  
  38. """my output -->
  39. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  40. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  41. --------------------------------------------------
  42. {'a': '1\n', 'c': '3\n', 'b': '2\n', 'd': '4'}
  43. {'3\n': 'c', '1\n': 'a', '4': 'd', '2\n': 'b'}
  44. """
Note:
If you use the print() function instead of the print statement this code will work with Python2 and Python3.
Last edited by vegaseat; Nov 8th, 2009 at 4:02 pm.
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Python Forum


Views: 241 | Replies: 7
Thread Tools Search this Thread



Tag cloud for Python
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC