Hi Peter, Thanks for the response! Several things you stated definitely got me thinking. I really appreciate the response. I used what you said and I am able to accomplish what I needed.
Thanks! Aaron On Mon, Dec 21, 2015 at 7:23 PM, Peter Otten <__pete...@web.de> wrote: > Aaron Christensen wrote: > > > Hello, > > > > I am trying to figure out how to populate a shelve file with a nested > > dictionary. > > > > These are my requirements: > > > > -Create shelve file called people.db > > -Append the shelve file with new people (person_1, person_2, etc.). > > -Use a for loop to iterate through 'attributes' so that I do not need to > > write out the lengthy code line by line to populate to the shelve file. > > -Need to reference shelve file data for future use > > > > Here is the key/value format that I would like to append to the shelve > > file. > > > > person_1 = { 'name': 'Bob', 'type': 'employee', 'attributes': > > [{'game': 'basketball', 'high score': '100', 'time': '3.34'}, > > {'game': 'bridge', 'high score': '10', 'time': '30.34'}, > > {'game': 'foosball', 'high score': '2', 'time': '24'}] > > ''' > > 50+ other attributes > > ''' > > } > > > > # Example: s['person_1]['attributes'][2]['time'] would call out '24'. > > # 's' is from 's = shelve.open('people')' > > I have a dictionary dictPeople.py file (created using pprint() that > > contains the information of person_1, etc. And I am extracting only a > > small percentage of the data that is needed. > > > > I have tried the following, but I get an invalid key error. > > > > import shelve, dictPeople > > s = shelve.open('people') > > person = 'person_1' > > s[person]['name'] = dictPeople.person_1['name'] > > s[person]['type'] = dictPeople.person_1['type'] > > # I need to use this for loop because there are 50+ attributes. > > for attribute in range(0, len(dictPeople['attributes'][attribute])): > > s[person]['attributes'][attribute]['game'] = \ > > dictPeople['attributes'][attribute]['game'] > > s[person]['attributes'][attribute]['high score'] = \ > > dictPeople['attributes'][attribute]['high score'] > > s[person]['attributes'][attribute]['time'] = \ > > dictPeople['attributes'][attribute]['time'] > > It turns out, I get the key error because I am not allowed to reference a > > key/value pair the same way that I can with a dictionary. However, the > > crazy thing is that I can call values in the db file using the same exact > > format when trying to write. > > > > For example: I can read data from the .db file using: > > > > x = s['person_1']['name'] > > print(x) > > BUT! I cannot write to that .db file using that exact format or I get an > > invalid key error. Makes no sense! > > > > s['person_1']['name'] = 'Bob' > > # Returns invalid key entry. Makes no sense. > > Therefore, I tried to extract data and populate the db file using the > > following: > > > > s[person] = { 'name': dictPeople.person_1['name'], > > 'type': dictPeople.person_1['type'], > > for attribute in range(0, len(dictPeople['attributes'][attribute])): > > ['game': dictPeople['attributes'][attribute]['game'], > > 'high score': dictPeople['attributes'][attribute]['high score'], > > 'time': dictPeople['attributes'][attribute]['time']] > > > > } > > But, this obvously doesn't work because of the for loop. How can I do > > this? > > > > -I am trying to figure out how to extract data from the dictionary > > dictPeople.py file and store it in the people.db file. > > -I am trying to add new people to the people.db file as more people > become > > available. > > -I need to use the for loop because of the 50+ attributes I need to add. > > -My future steps would be to modify some of the data values that I > extract > > and used to populate the people.db file, but my first step is to, at > > least, extract, and then populate the people.db file. > > > > Any help or guidance is greatly appreciated. Thank you for your time and > > reading my question. > > You don't need these loops. The problem is that when you read the dict from > the db > > db = shelve.open(...) > person = db["person_1"] > > person is a Python object completely independent of the shelve and the > shelve has no way to trace changes to that object: > > $ python3 > Python 3.4.3 (default, Oct 14 2015, 20:28:29) > [GCC 4.8.4] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import shelve > >>> db = shelve.open("tmp.shelve") > >>> person_1 = { 'name': 'Bob', 'type': 'employee', 'attributes': > ... [{'game': 'basketball', 'high score': '100', 'time': '3.34'}, > ... {'game': 'bridge', 'high score': '10', 'time': '30.34'}, > ... {'game': 'foosball', 'high score': '2', 'time': '24'}] > ... } > >>> db["person_1"] = person_1 > >>> db["person_1"]["age"] = 42 > >>> db.close() > >>> db = shelve.open("tmp.shelve") > >>> db["person_1"] > {'name': 'Bob', 'type': 'employee', 'attributes': [{'time': '3.34', 'high > score': '100', 'game': 'basketball'}, {'time': '30.34', 'high score': '10', > 'game': 'bridge'}, {'time': '24', 'high score': '2', 'game': 'foosball'}]} > > When you look at the data you see that there is no "age" key. The straight- > forward fix is to always use an assignment > > db[key] = new_value > > when you want a change: > > >>> person = db["person_1"] > >>> person["age"] = 42 > >>> db["person_1"] = person > >>> db.close() > > That way the change will survive: > > >>> db = shelve.open("tmp.shelve") > >>> db["person_1"]["age"] > 42 > > Alternatively you can open the shelve with writeback=True: > > >>> db = shelve.open("tmp.shelve", writeback=True) > >>> db["person_1"]["height"] = 2.0 > >>> db.close() > >>> db = shelve.open("tmp.shelve", writeback=True) > >>> db["person_1"]["height"] > 2.0 > > That way every value will be written back (even when you don't modify it) > and therefore all mutations persist, but you pay for the convenience with > superfluous caching and writing. > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list