Dynamic Dictionary Creation

Bob van der Poel bvdpoel at kootenay.com
Fri Dec 6 18:08:26 EST 2002


Carl Banks wrote:
> 
> Bob van der Poel wrote:
> >
> > I'm writing a program which needs to convert note lengths specified in
> > somewhat standard musical notation to midi ticks. I have a function
> > which does this with
> > a dictionary lookup. An abreviated version is shown here:
> >
> > def getNoteLen(x):
> >   global TicksQ
> >   ntb = { '1': TicksQ *
> > 4,
> >      '2': TicksQ * 2,
> >      '4': TicksQ,
> >      '8': TicksQ
> > }
> >
> >   return ntb[str(x)]
> >
> > What I'm concerned about is the initialization of the table. Am I
> > correct in assuming that each time I access the function the values in
> > the table will be recalculated?
> 
> Yep.  Not only that, but the dictionary itself will be recreated every
> time the function is called.  For this example, that could be more
> time consuming than the arithmetic.
> 
> 
> > I suppose I could make the table global and avoid this?
> 
> That's what I suggest you do.  Globals are not evil when used to store
> a table of unchanging data.

Oppps, I thought the Global == Evil. Always :)

But, you are correct that this is the easiest way to handle it.

> > I could avoid runtime math by replacing TicksQ with a value, but I've
> > always been taught not to use literal magic numbers, and python doesn't
> > have a DEFINE statement.
> 
> Even if you did that, Python would still regenerate the dictionary
> every function call.  That is far from efficient.  I suggest you keep
> TicksQ and just make the table global.
> 
> There is one other optimization you can make.  Dictionaries do not
> require strings as keys; you can use integers.  So you can do this:
> 
> ntb = { 1: TicksQ * 4,
>         2: TicksQ * 2,
>         3: TicksQ,
>         4: TicksQ }
> 
> def getNoteLen(x):
>     return ntb[x]
> 
> And, because getNoteLen is now a trivial function, I would get rid of
> it and just use the dictionary directly.

Yes, well, the joys of having simple examples. My real program is a bit
more complicated and the notes are not a simple 1,2, etc. Actually, I
have 'notes' like

	1 - whole note
	4 - quarter note
	4+8 - dotted eighth
	1+1 - a 8 beat

So, my function needs to rip apart the strings. And since we've got
strings at that point, might as well use them as keys.

Thanks!
-- 
Bob van der Poel ** Wynndel, British Columbia, CANADA **
EMAIL: bvdpoel at kootenay.com
WWW:   http://www.kootenay.com/~bvdpoel



More information about the Python-list mailing list