| | |
strange dictionary definition/object instance problem
![]() |
•
•
Join Date: May 2008
Posts: 6
Reputation:
Solved Threads: 0
I am trying to add entries to a dictionary with the following loop:
however, earlier entries of the dictionary are being 'overwritten' with new values as follows:
(here's the output from the code print statements)
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.200'}, 'Blade1INLET': {'WG': '3.191'}, 'Blade2INLET': {'WG': '3.200'}, 'Vane1INLET': {'WG': '3.191'}}}}
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}}
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.5': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}}
So what's happening?
Note that #### in:
SHOULD NOT CHANGE WITH ITERATION based on the loop
python Syntax (Toggle Plain Text)
for p in pressures: q70in.resetKeyword( "expansionRatio", p ) q70in.writeInput( prefix + tempInput ) commands.getstatusoutput( runq70 ) q70out = q70.Q70Output( prefix + outputFile ) results[p] = {} #results[p]['Performance'] = q70out.performance results[p]['Conditions'] = q70out.conditions print q70out print results print ''
however, earlier entries of the dictionary are being 'overwritten' with new values as follows:
(here's the output from the code print statements)
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.200'}, 'Blade1INLET': {'WG': '3.191'}, 'Blade2INLET': {'WG': '3.200'}, 'Vane1INLET': {'WG': '3.191'}}}}
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}}
<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.5': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}}
So what's happening?
Note that #### in:
Python Syntax (Toggle Plain Text)
results{ '2.0':{'Conditions':{'Vane2INLET':{'WG': ####}}}}
SHOULD NOT CHANGE WITH ITERATION based on the loop
•
•
Join Date: Dec 2006
Posts: 977
Reputation:
Solved Threads: 273
New entries are not being over-written. You are initializing to an empty dictionary with the statement results[p] = {}. Perhaps (and just perhaps) a dictionary of classes would serve better. Note that SQLite can also be used in memory, i.e you can store and lookup '2.0' + 'Conditions' + 'Vane2INLET', etc. or however you want to store it. Either would be less confusing IMHO.
Python Syntax (Toggle Plain Text)
class Class1 : def __init__ (self) : self.field1 = "" self.field2 = 0 self.field3 = "***" #==================================================== sample_dic = {} C = Class1() C.field1 = "Test1" C.field2 = 1 C.field3 = "Test1A" sample_dic["test1"] = C C = Class1() C.field1 = "Test2" C.field2 = 2 C.field3 = "Test2A" sample_dic["test2"] = C C = Class1() sample_dic["test3"] = C ## note that dictionary keys are not in any order for key in sample_dic.keys() : print key, sample_dic[key].field1, sample_dic[key].field2, \ sample_dic[key].field3 sample_dic["test3"].field2=3 print "updated field2 =", sample_dic["test3"].field2
Last edited by woooee; May 13th, 2008 at 5:00 pm.
•
•
Join Date: May 2008
Posts: 6
Reputation:
Solved Threads: 0
i'll definitely give the dictionary of classes a try, but i still think i might be missing something...
'results[p] = {}' should only initialize that key's value since every value of 'p' is unique. for example:
{0: 0, 1: {}, 2: 2}
'results[p] = {}' should only initialize that key's value since every value of 'p' is unique. for example:
python Syntax (Toggle Plain Text)
dict = {} dict[0] = 0 dict[1] = {} dict[2] = 2 print dict
{0: 0, 1: {}, 2: 2}
•
•
Join Date: Dec 2006
Posts: 977
Reputation:
Solved Threads: 273
•
•
•
•
i'll definitely give the dictionary of classes a try, but i still think i might be missing something...
'results[p] = {}' should only initialize that key's value since every value of 'p' is unique. for example:
python Syntax (Toggle Plain Text)
dict = {} dict[0] = 0 dict[1] = {} dict[2] = 2 print dict
{0: 0, 1: {}, 2: 2}
Last edited by woooee; May 13th, 2008 at 5:11 pm.
•
•
Join Date: May 2008
Posts: 6
Reputation:
Solved Threads: 0
i just tried the dictionary of classes approach and it didn't work... I also added some more printing. Here's the snippet and output:
<type 'str'> 3 2.0
2.0
{'Stage1': {'REAC-PS': '0.509', 'WR(T)/P': '4.3010', 'TT0': '1602.30', 'REAC-W': '0.515', 'W0': '3.191', '0WR(THCR)E/D': '2.8191', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.488', 'WR(T)/P': '6.0074', 'TT0': '1470.43', 'REAC-W': '0.500', 'W0': '3.200', '0WR(THCR)E/D': '3.9309', 'PT0': '20.4275'}}
<type 'str'> 3 3.0
2.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
3.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
<type 'str'> 3 3.5
2.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.5
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
python Syntax (Toggle Plain Text)
for p in pressures: q70in.resetKeyword( "expansionRatio", float(p) ) q70in.writeInput( prefix + tempInput ) commands.getstatusoutput( runq70 ) q70out = q70.Q70Output( prefix + outputFile ) #results[p] = {} #results[p]['Performance'] = q70out.performance #results[p]['Conditions'] = q70out.conditions results[p] = indyResult() results[p].performance = q70out.performance results[p].conditions = q70out.conditions print type(p), len(p), p for i in results: print i print results[i].performance
<type 'str'> 3 2.0
2.0
{'Stage1': {'REAC-PS': '0.509', 'WR(T)/P': '4.3010', 'TT0': '1602.30', 'REAC-W': '0.515', 'W0': '3.191', '0WR(THCR)E/D': '2.8191', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.488', 'WR(T)/P': '6.0074', 'TT0': '1470.43', 'REAC-W': '0.500', 'W0': '3.200', '0WR(THCR)E/D': '3.9309', 'PT0': '20.4275'}}
<type 'str'> 3 3.0
2.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
3.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
<type 'str'> 3 3.5
2.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.5
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
•
•
Join Date: Jul 2006
Posts: 608
Reputation:
Solved Threads: 149
What's happening is that dictionaries, like lists, are mutable objects. Furthermore, they are assigned by reference and not by value. So under certain conditions, you might think you are changing one mutable object when in fact you are changing all of the ones that are referenced:
Now as far as I can tell, the issue here is subtle. These two functions illustrate the problem:
The difference between the first version and the second is that mydict is getting clobbered successively. I *think* that's what's happening with q70out.conditions. I suspect there's a bug in the code for q70.Q70Output( prefix + outputFile ) that returns a mutable object that's getting clobbered every time.
I whole-heartedly agree with wooeee ... your data structure would be a whole lot happier as a class object with members called .conditions and .performance.
Jeff
Python Syntax (Toggle Plain Text)
>>> a = [] >>> b = a # b and a point to the same list now. >>> b.append(1) >>> b [1] >>> a [1] >>>
Now as far as I can tell, the issue here is subtle. These two functions illustrate the problem:
Python Syntax (Toggle Plain Text)
>>> def test_func(): results = {} for x in range(4): results[x] = {} results[x]["conditions"] = x print results >>> test_func() {0: {'conditions': 0}, 1: {'conditions': 1}, 2: {'conditions': 2}, 3: {'conditions': 3}} >>> >>> def test_func2(): results = {} mydict = {} for x in range(4): results[x] = mydict results[x]["conditions"] = x print results >>> test_func2() {0: {'conditions': 3}, 1: {'conditions': 3}, 2: {'conditions': 3}, 3: {'conditions': 3}} >>>
The difference between the first version and the second is that mydict is getting clobbered successively. I *think* that's what's happening with q70out.conditions. I suspect there's a bug in the code for q70.Q70Output( prefix + outputFile ) that returns a mutable object that's getting clobbered every time.
I whole-heartedly agree with wooeee ... your data structure would be a whole lot happier as a class object with members called .conditions and .performance.
Jeff
Last edited by jrcagle; May 13th, 2008 at 9:52 pm.
•
•
Join Date: Dec 2006
Posts: 977
Reputation:
Solved Threads: 273
This is a very simple example of how you could use SQLite in memory. This may be a case of the difficult way actually being the simpliest. Note that this is just a simple/quick example. There is a lot more on the web. If this is of some help you can thank The Blues. I was looking for something that I could do while listening to Bad Dog Blues.
Python Syntax (Toggle Plain Text)
import sqlite3 as sqlite ##---------------------------------------------------------------------- def add_rec(cur, con, add_tuple): print "add_rec", len(add_tuple) cur.execute("insert into test_it values (?, ?, ?, ?, ?, ?, ?, ?, ?)", add_tuple) con.commit() ##---------------------------------------------------------------------- def print_all_recs(cur): # Execute the SELECT statement: print "Printing all recs" cur.execute("select * from test_it") # Retrieve all rows as a sequence and print that sequence: recs_list = cur.fetchall() for rec in recs_list: print rec print " stage, REAC_W =", rec[1], rec[5] ##---------------------------------------------------------------------- def add_test_data(cur, con): #-----> Stage REAC_PS WR(T)/P TTO REAC_W W0 0wR(THCR)E/D PTO data_list=[ ('2.0', 'Stage1', '0.509', '4.3010', '1602.30', '0.515', '3.191', '2.8191', '29.7010'), \ ('2.0', 'Stage2', '0.488', '6.0074', '1470.43', '0.500', '3.200', '3.9309', '20.4275'), \ ('2.0', 'Stage1', '0.524', '4.4623', '1602.30', '0.560', '3.311', '2.9243', '29.7010'), \ ('2.0', 'Stage2', '0.579', '6.6682', '1444.78', '0.700', '3.320', '4.3593', '18.9262'), \ ('3.0', 'Stage1', '0.524', '4.4623', '1602.30', '0.560', '3.311', '2.9243', '29.7010'), \ ('3.0', 'Stage2', '0.579', '6.6682', '1444.78', '0.700', '3.320', '4.3593', '18.9262'), \ ('3.5', 'Stage1', '0.525', '4.4695', '1602.30', '0.563', '3.316', '2.9290', '29.7010') ] for data_tuple in data_list : add_rec(cur, con, data_tuple) ##---------------------------------------------------------------------- if __name__ == "__main__": # Create a connection to the (memory) database file con = sqlite.connect(':memory:') # Get a Cursor object that operates in the context of Connection con cur = con.cursor() cur.execute("CREATE TABLE test_it (number varchar, stage varchar, REAC_PS varchar, WR_T_P varchar, TTO varchar, REAC_W varchar, W0 varchar, wR_THCR_E_D varchar, PTO varchar)") add_test_data(cur, con) print_all_recs(cur) ##---------------------------------------------------------------------- print '\n-----SELECT * FROM test_it where number="2.0"-------' recs_list=cur.execute('SELECT * FROM test_it where number="2.0"') ctr=0 for row in recs_list: print row ctr += 1 print ctr, "recs found" print '\n-----SELECT * FROM test_it where number="2.0" and stage="Stage1"' lookup_dic={"dic_num":"2.0", "dic_st":"Stage1"} recs_list=cur.execute('SELECT * FROM test_it where number=:dic_num and stage=:dic_st', \ lookup_dic) ctr=0 for row in recs_list: print row ctr += 1 print ctr, "recs found"
Last edited by woooee; May 13th, 2008 at 11:55 pm.
•
•
Join Date: May 2008
Posts: 6
Reputation:
Solved Threads: 0
Thanks a ton for the help and great example, woooee & jrcagle! i did a little google'ing since i have absolutely no experience with sql, but it does seem like a really good fit for this type of application. i'll give it a try this morning and see if i can't get things working. i'll post the resolution upon completion.
-john
-john
![]() |
Other Threads in the Python Forum
- Previous Thread: Adding tabs from plugins
- Next Thread: Power Set List from Input List
| Thread Tools | Search this Thread |
alarm ansi anydbm app assignment backend beginner binary bluetooth character cipher cmd coordinates customdialog cx-freeze data decimals development directory dynamic exe feet file float format function generator getvalue gnu graphics halp handling heads homework http ideas input ip itunes java keycontrol leftmouse line linux list lists loop maintain maze millimeter module mouse number numbers output parsing path pointer prime programming progressbar push py2exe pygame pymailer python queue random recursion recursive schedule screensaverloopinactive script slicenotation sqlite ssh statistics string strings sudokusolver text thread time tlapse tuple ubuntu unicode url urllib urllib2 variable ventrilo vigenere web webservice wikipedia write wxpython xlib xlwt





