append to items depending on prior item

Alex Martelli aleaxit at yahoo.com
Mon Oct 4 03:14:29 EDT 2004


M. Clift <noone at here.com> wrote:
   ...
> What I want to do is append to each item an extra value depending on the
> previous item.
> 
> Too keen to get help, what I should have written is;
> 
> What I want to do is append to each item an extra value depending on the
> previous item and itself.

So, you mean the key is not just the previous, but the pair
(previous,item)?  OK, not necessarily a big difference...: you can
either use the pairs as keys, or make a nested dictionary.

> Alex gave me this;
> 
> def weird_appender(sequence):
>     choices = dict({None: 'abc'}, item1='abc', item2='def')

Change this to something like:

# what if there IS no 'previous item', i.e., the first time, or for
# all those cases which are not explicititly in the dictionary...:
first_time_choices = {'item1': 'abc', 'item2': 'def', }
# general case
choices = { None: first_time_choices,
            'item1': {'item1': 'blu', 'item2': 'ghi', },
            'item2': {'item1': 'jkm', 'item2': 'nop', },
          }

>     previous = None
>     for item in sequence:
>         yield item+random.choice(choices.get(previous, choices[None]))
>         previous = item

and here, access the nested dicts -- clearer when done less concisely,
in separate steps rather than all inline:
          d = choices.get(previous, first_time_choices)
          choose = d.get(item, [''])
          yield item + random.choice(choose)
          previous = item

>         print weird_appender(sequence)

this is misaligned -- remove leading space, I don't know how it got
there (it definitely wasn't there in my post!!!).  The 'p' of print must
align with the 'd' of 'def weird...'.  The print is done after the
function weird_appender is done being defined, most definitely *NOT* as
part of the 'for' loop in said function's body...!!!

> 
> What I want to do is append to an item, but rather than just getting this
> value based on the previous choice
> I'd like to say if previous item is 'item1a' and the current item is item2

Ah, you want to key on the previous _output_ item rather than the
previous _input_ one?  OK, then further alter in the latest snippet the
last two statements to be instead:

          previous = item + random.choice(choose)
          yield previous

> append some choice. or else if the current item is
> item3 append a diferent choice.

If you LIKE to say if/else if, there's nothing stopping you from saying
it.  I think the dictionary accesses are clearer, but changing them into
a few nested if/elif/else trees is hardly difficult - it just (IMHO)
worsens the code's quality, that's all.

 
> Now, I know none of you are on my payroll (and I have been asking for help a
> lot), but if that is easy to impliment I would be grateful
> if someone could show me how. However, if it isn't so easy to do, is the
> previous code Alex gave me along the right lines for my new requirement?

If your requirement is now correctly expressed and divined, yes.  If you
gave us the true requirement (what application problem are you actually
trying to solve) rather than asking for advice on how to implement one
design you appear to have already chosen, we might be on a sounder basis
in making such statements, of course.

> So that if I go away and change / add to it myself I might eventually get it
> to work. If not, could someone point me in the direction I should look
> at other than a dictionary method. I see it as a sort of multiplication
> lookup table i.e. previous items already appended are looked for along the
> x axis, the current item unappended is on the y axis, reading along from
> both gives the value to append to the current item.

Right, the nested dictionaries give you something akin to a 2-d array,
except that each axis is indexed by string rather than by number.
Again, this contrasts with your assertion in this very post that you'd
LIKE to say "if" and "else" -- the dictionaries are there exactly in
order to _avoid_ the rich nesting of 'if/elif/else' trees, moving some
complexity from code to "data tables".


> Thanks for putting up with me,

No problem, really.


Alex



More information about the Python-list mailing list