[Tutor] updating a list under conditions -- I think my way might "smell"

Brian van den Broek bvande at po-box.mcgill.ca
Mon Oct 4 21:03:58 CEST 2004


Hi All,

To avoid a *really* long post (i.e. > 400 lines of quotation), I am 
giving a synopsis, with links to originals.

<SYNOPSIS>

I posted a question 
<http://mail.python.org/pipermail/tutor/2004-October/032230.html>.

Summary of my question:
I was uncertain of my method of updating a list subject to two 
conditions, the second of which might not be met. If it wasn't met, I 
wanted the new list item at them end, otherwise I wanted it before the 
item that met the second condition, amongst the items after the one that 
met the first condition.

I was was using an assignment like my_list[i:i] = new_item where i is 
the index of the item meeting the second condition. This works if there 
is such an item, but not if there isn't. So, I was starting with i as 
'', updating it if and when the second condition was met, and then 
wrapping the assignment in a try/except, with the accept block doing 
my_list.append(new_item). I was worried about the procedure perhaps 
"smelling" a bit, and asked if there was a better way.

I mentioned that the list was to store order of appearance in a data 
structure of the items in a dictionary.


Chad Crabtree posted a reply 
<http://mail.python.org/pipermail/tutor/2004-October/032247.html>
which gave me his reworking of Wolfgang Grafen's Sequential Dictionary Class
<http://home.arcor.de/wolfgang.grafen/Python/Modules/AllOs/LIB/DICTS/SEQDICT/hide/NDICT.PY>.

</SYNOPSIS>


So, thanks Chad! That was a fair bit of code, and I am not yet too 
familiar with doing things the OOP way, so I haven't managed to grok it 
all yet. But, judging from what I have understood of it, it does look 
like something that would have made my overall program design smoother 
if I'd had it a week ago. Oh well, there will be a next time, I am sure 
:-) So thanks for the substantial help!

I freely admit I may have missed the part of the class which would 
directly help with my list updating problem, but I don't seem to see 
anything in there that speaks to it. (My code-reading skills aren't 
orders better than my grasp of OOP, I'm afraid.)

However, if anyone ends up hitting my original question with a google, I 
think I have a better way now.

The relevant bit of my posted solution that left me unhappy was:

def get_insert_location(target, start):
      location = ''
      # location given a value that evaluates to 'False' and that
      # cannot serve as a list index. (Elsewhere in my code I need
      # to be able to do an if test on location, so I need the False.)
      for i in target[start:]:
          if my_dict[i] > 90:
              # "Condition B" in the description above.
              # there may not be such an i. If there is, use its index.
              location = target.index(i)
              break
      return location

def update(target, item):
      start_search = find_first_not_multiple_of_10(target) + 1
      # function find_first_not_multiple_of_10 def'ed in my original post
      # omitted as not really of relevance here.
      # + 1 to get past the first A-meeter
      location = get_insert_location(target, start_search)
      try:
          target[location:location] = [item]
      except TypeError:
          # error raised if there is no i in target[start:] such that
          # my_dict[i] > 90. If raised, put new item at end.
          target.append(item)
      print target

It has since occurred to me that in get_insert_location(target, start) 
above, I could just have

location = len(target)

at the beginning in place of

location = ''

Then, in update(target, item)

target[location:location] = [item]

will work, even if the second condition was not met. This gets rid of 
the try/except, at the cost of being able to do the needed if test on 
location. (As mentioned in the comments, I wanted location to evaluate 
to False if there was no item meeting the second condition. This is used 
elsewhere in my program from which the situation represented in my toy 
example that I posted is drawn from.) But I realized perhaps it wasn't a 
good idea to try to make location do two distinct jobs, so I replaced 
that with a separate name storing whether condition B was met. (In fact, 
in retrospect, my problem was caused by trying to make location do such 
a double duty.)

And that, at least to my nose, removed the "smell".

Anyway, this is more than long enough. But thanks again Chad for a most 
useful looking solution to using dicts together with order information 
of values.

Best to all,

Brian vdB



More information about the Tutor mailing list