Dict -> Dict -> List -> List data structure help.

Manuel M. Garcia mgarcia at cole-switches.com
Mon Nov 4 15:00:02 EST 2002


On Sat, 2 Nov 2002 21:44:49 -0500, "Wayne R" <wayne at tbnets.com> wrote:

>
> I am trying to create a complex data structure and I can't seem to
>figure out how to arrange the dict and list constructs.  Here's the
>basic scheme.  
>
> Dictionary ->    Dictionary            -> List                   ->
>List
> (Store #)        (Transaction #)      (Line # of transaction)
>(Details of transaction line)
> (usually 1,2,3)  (six digit A-X,1-9)  (1-999)                   (Sku
>number, description, extended price) 
>
> Any ideas greatly welcomed.
>
>Wayne
>

This program is a lot more fun to write using generators.  I have
written too many little programs like this one in Python and other
languages, this is the first time I have used generators, and boy
howdy, does it make the code come out clean!

I shudder to think of all the times I have written similar programs in
Visual Basic!

When I write programs like this, I always throw extra data on at the
end, so EOF is no longer a special case.

I think you will find it is easier to have a single dictionary that
stores lists of lists.  Remember that Python lets you use things like
(7, 'XYZ123') as keys to dictionaries, and really that is the easiest
way to go.  You can think of it as getting 'sort by store, then by
transaction' for free!

Manuel

from __future__ import generators
import shlex, StringIO

shlex0 = shlex.shlex( StringIO.StringIO( """

store:2 trans:CDE345 ;
* 1234567 'six-pack of beer' $1.66 ;
* 2345678 'twinkies' $1.77 ;
* 3456789 'cancer sticks' $3.44 ;
store:1 trans:BCD234 ;
* 4567890 'magic muffins' $6.66 ;
* 5678901 'AAA batteries' $3.22 ;
store:2 trans:ABC123 ;
* 5789012 'bottled water' $10.00 ;

""" ))

shlex0.wordchars = '%s:$.' % shlex0.wordchars

def get_tokens():
    while 1:
        token = shlex0.get_token()
        if not token: break
        yield token
    # extra ';' to guarantee line gets flushed
    yield ';'

def get_lines():
    line0 = []
    for token in get_tokens():
        if token == ';':
            if line0: yield line0
            line0 = []
        else:
            line0.append(token)
    # extra to guarantee list gets flushed
    yield ['store:-1', 'trans:XXXXXX']

trans_info = {}
store = -1
trans = 'XXXXXX'
list0 = []
for line0 in get_lines():
    if line0[0] != '*':
        if list0: trans_info[(store,trans)] = list0
        list0 = []
        store = int(line0[0].split(':')[1])
        trans = line0[1].split(':')[1]
    else:
        list0.append( [line0[1],
                       line0[2][1:-1],
                       float(line0[3][1:])] )

keys = trans_info.keys()
# very easy to sort by store, then transaction!
keys.sort()
for store, trans in keys:
    print 'Store#%i, Transaction#%s' % (store, trans)
    list0 = trans_info[(store,trans)]
    for i in range(len(list0)):
        t = [i+1]
        t.extend(list0[i])
        print '    %i %s %r $%.2f' % tuple(t)




More information about the Python-list mailing list