common problem - elegant solution sought

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Tue Jan 15 06:55:36 EST 2008


On Tue, 15 Jan 2008 11:33:36 +0100, Helmut Jarausch wrote:

> Hi,
> 
> I'm looking for an elegant solution of the following tiny but common
> problem.
> 
> I have a list of tuples  (Unique_ID,Date) both of which are strings. I
> want to delete the tuple (element) with a given Unique_ID, but I don't
> known the corresponding Date.
> 
> My straight forward solution is a bit lengthy, e.g.
> 
> L=[("a","070501"),("b","080115"),("c","071231")] pos=-1
> found=-1
> for (Key,Date) in L :
>      pos+= 1
>      if  Key == "b" :
>          found= pos
>          break
> 
> if  found >= 0 :
>      del L[found]
> 
> print L
> 
> Most probably there are much more elegant solutions. Unfortunately, the
> index-list-method doesn't take an additional function argument for the
> comparisons.


Your code mixes two distinct steps into one, and therefore becomes a 
little messy. I suggest you change your problem to the two step problem 
(1) find an item with the given key; and (2) delete it.

Here's a solution to the first part:

def find_by_key(L, key, where=0):
    """Search the 'where'th position of elements of L."""
    for i, x in enumerate(L):
        if x[where] == key:
            return i
    return -1  # or raise an exception


And the second:

pos = find_by_key(L, 'b')
if pos != -1:
    del L[pos]

This too could be made into a function, if necessarily.



How else could we solve this problem?

class Tester(object):
    def __init__(self, key, where=0):
        self.key = key
        self.where = where
    def __eq__(self, other):
        return other[self.where] == self.key


L = [("a", "070501"), ("b", "080115"), ("c", "071231")]
L.index(Tester("c"))


But beware, this technique might not generalize to arbitrary elements in 
the list L. It should work if the elements are tuples, but may not work 
if they are a custom class.


-- 
Steven



More information about the Python-list mailing list