moving items in a list

Jack Diederich jack at performancedrivers.com
Tue Jan 7 18:36:05 EST 2003


On Tue, Jan 07, 2003 at 03:30:07PM -0600, Mark McEahern wrote:
> Below is some code and unit tests to demonstrate how I'm moving items in a
> list.  It works, but I'm sure I'll learn a lot by any feedback you care to
> offer.
> 
> """
> move 'up' means move the item once towards the first item.
> 
> """

Here are a few examples of move_up, most of them useless and pedantic.
The simple one is faster than your example, some of the others are 50%
slower and abuse language features.

enjoy,

-jack
    
def move_up(l, m):
    """Simple move_up, no frills, pretty quick"""
    for i in range(1,len(l)):
        if l[i] in m:
            # slower (but more pythonic?) than using a swap temporary
            l[i-1:i+1] = [l[i], l[i-1]]
        
def move_up_redux(l, m):
    """Use reduce() and a function to fool around"""
    def redux(anchor, ele):
        if anchor and ele in m:
            anchor[-1:] = [ele, anchor[-1]]
        else:
            anchor.append(ele)
        return anchor
    l[:] = reduce(redux, l, []) # replace the entire contents of l

def move_up_sort(l, m):
    """Highly dependent on the implementation of sort(), I'm afraid"""
    seen = {}
    cmpd = {}
    def crazysort(a, b):
        if (a in m and b not in m):
            if (a in seen and seen[a] == b):
                ret = -1
            elif (a not in seen and b not in cmpd):
                seen[a] = b
                ret = -1
            else:
                cmpd[b] = 1
                ret = 0
        else:
            cmpd[b] = 1
            ret = 0
        return ret
    l.sort(crazysort)

def move_up_spans(l, m):
    """don't do pair assignments, see if we can collect a run to move
    all at once"""
    guy = None
    pos = None
    i = 1
    while (i < len(l)):
        if (guy is None):
            if (l[i] in m):
                guy = l[i-1]
                pos = i - 1
            else:
                i += 1
        else:
            if (l[i] not in m):
                l[pos:i] = l[pos+1:i] + [guy]
                guy = None
            else:
                i += 1
    if (guy is not None):
        l[pos:i] = l[pos+1:i] + [guy]





More information about the Python-list mailing list