[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 08:09:30 CEST 2004


Hi All,

I have a situation where I have a list of dictionary keys, representing 
the order of occurrence of the dictionary values in some datafile. (In 
my actual case, the values are themselves dictionaries, storing metadata 
on the data items in the file.)

I want to add a new value to the dictionary, putting its key in the list 
such that it occurs after the first key that meets condition A and 
before the first (among those strictly after the A-meeter) that meets 
condition B.

Given my data, I know condition A will be met by an early item in the 
list of dictionary keys. Condition B might not be meet amongst the post 
A-meeter items. (It is certain to be met before, but if it is, meeting 
condition B is not relevant.) If it is not, I want to add my new item at 
the end of the list that stores the orders.

I have a way that works, but I'm not too sure about it's "smell". The 
sample code below abstracts my working method into a manageable toy 
example. (My actual use has fairly complicated conditions, and I found 
it easier to write ones which just displayed the logic I am worried 
about than to extract the relevant functions in a way that would leave 
them short enough to post, yet still in a runnable state.) So, I'm not 
advancing the broad design here as good. It's just a quick way to 
illustrate the use  of location = '' and the try/except block that form 
the heart of my present solution.

def find_first_not_multiple_of_10(target):
     for i in target:
         if 0 != my_dict[i] % 10:
             # "Condition A" in the description above.
             # Given my data, I am certain such an i exists early in
             # the list I am working with. It could even be first.
             return i

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
     # + 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

my_dict = {1:110, 2:35, 3:50, 4:80, 5:95, 6:70}
my_list = [1, 3, 2, 6, 5, 4]
my_list2 = [1, 3, 2, 6, 4]  # The item meeting "Condition B" removed

my_dict[7] = 45
update(my_list, 7)
update(my_list2, 7)

 >>>
[1, 3, 2, 6, 7, 5, 4]
[1, 3, 2, 6, 4, 7]

So, this way works as desired. But is there a better way to do this?

I get that that is hard to answer seeing neither the data I am working 
on, nor the reason I need the if test on location, etc. But my script is 
pushing to 1,000 lines and the data is many MB, so that just isn't 
practical to post ;-)

Best and thanks to all,

Brian vdB



More information about the Tutor mailing list