Dictionaries -- ahh the fun.. (newbie help)

BJörn Lindqvist bjourne at gmail.com
Tue May 9 19:04:47 EDT 2006


> Can someone help me out.  I am trying to determing for each run whether
> or not the test should pass or fail but I can't seem to access the
> results ..
>
> Alternatively can someone suggest a better structure ( and a lesson as
> to the reasoning ) that would be great too!!

Flat is better than nested. Pretend you write one billion cells in
your cells dict. To save disk space and memory (and make code
readable!) you wan't to make your structure as optimal as possible.

[snip]
> cells["NOR3X1"]= {
>                     'run'       : [ 'lvs', 'drc' ],
>                     'results'   : [{ 'lvs' : 'pass' },
>                                    { 'drc' : 'fail' }]
>                  }
[snip]
> def main():
>
>     for cell in cells:
>         print cell
>         for run in cells[cell]['run']:
>             print cell, run, "should",
> cells[cell]['results'].index(run)

That is good code and AFAICT it should work as you have described.
Just replace cells[cell]['results'].index(run) with
cells[cell]['results'][run]

However, notice how you have defined each cell:

> cells["NOR3X1"]= {
>                     'run'       : [ 'lvs', 'drc' ],
>                     'results'   : [{ 'lvs' : 'pass' },
>                                    { 'drc' : 'fail' }]
>                  }

Here you have repetition, you are writing the string lvs and drc
twice. Imagine you have hundreds of these in each cell, wouldn't it be
annoying to have to type so much redundant data. So you optimize the
structure:

cells["NOR3X1"] = {'run' : [('lvs', 'pass'), ('drc', 'fail')]}

Your code for printing the results become:

for cell, d in cells.items():
    print cell
    for testname, testresult in d['run']:
        print cell, testname,  'should', testresult

for cell, d in cells.items() runs through all the key-value pairs in
the dict. cell becomes "NOR3X1" (the key) and d becomes {'run' :
[('lvs', 'pass'), ('drc', 'fail')]} (the value) for one loop for
example. for testname, testresult in d['run'] runs through all items
in the list d['run'] and "unpacks" them. testname becomes 'lvs' and
testresult 'pass' for one loop for example.

The next step in this refactoring is realizing that all items in the
cell dict are a dict with just one element. I.e: {'run' : ('drc',
'fail')} for the 'AND3X1' item. So you can optimize your structure
another step:

cells["NOR3X1"] = [('lvs', 'pass'), ('drc', 'fail')]

Here, we have just removed the subdict. Dicts with just one item are
rarely useful so we replace the dict with its sole item. This I think
is the optimal structure for your example, because it contains no
needless repetition. The following is your original example using the
reworked cells structure.

P = 'pass'
F = 'fail'
cells['NOR3X1'] = [('lvs', P), ('drc', F)]
cells['OR3X1'] = [('lvs', P')]
cells['AND3X1] = [('drc', F)]

for cellname, celltests in cells.items():
    print cellname
    for testname, restresult in celltests:
        print cellname, testname, 'should', testresult

As you can see I have replaced the 'pass' and 'fail' strings with the
variables P and F. Sometimes that is a useful technique because it
reduces repetitive typing. You are also less likely misspell things
like 'flai' instead of 'fail'. One golden rule of programming is that
you should never write the same thing twice. Ofcourse that is very
hard to achieve in practice, but the stronger you get the less often
you do it. If you can spot that you have written something twice or
more times in your code, then you have also spotted what is wrong with
your code.

--
mvh Björn



More information about the Python-list mailing list