__setitem__ puzzle

Anton Vredegoor anton at vredegoor.doge.nl
Mon Apr 21 13:35:06 EDT 2003


"Bjorn Pettersen" <BPettersen at NAREX.com> wrote:

>          root = y         # save 1st level mutable items

Thanks a lot!

>Is equivalent to L[1,1,1], and you can also do fun things like L[1:2,
>4:9]. Advice: special case one tuples (L[n]).

Hmm, I hadn't thought about slicing. I think raising an error for
arguments without len() defined is a feature. One could always use
(0,) if necessary. This way it's clear that it's not a list.

By the way, see below for the reason this came up. Using different
filter expressions on the result of the indices function it's possible
to make a list of all leaf nodes or do other tree-like operations on a
list (not shown here).

Anton

#By Anton Vredegoor anton at vredegoor.doge.nl Apr 21, 2003
# with some help by Bjorn Pettersen

from __future__ import generators
False,True = 0,1

class indexer:

    def __init__(self,maxima = []):
        self.maxima = maxima
        self.indices = [0 for i in range(len(maxima))]
    
    def __iter__(self):
        maxima,indices = self.maxima, self.indices
        while maxima:            
            yield tuple(indices)
            indices[-1]+=1
            while indices[-1] == maxima[-1]:
                maxima.pop()
                indices.pop()
                indices[-1]+=1

    def addlevel(self,n,start=0):
        self.maxima.append(n)
        self.indices.append(start)

class indexable(list):
    
    def __getitem__(self,x):
        y = self[:]
        for z in x:
            y = y[z]
        return y

    def __setitem__(self,x,val):
        root = y         # BP: save 1st level mutable items
        for z in x[:-1]:
            y = y[z]
        y[x[-1]] = val
        self[:] = root   # BP: update 1st level mutable items
       
def issequence(item):
    try:
        item + ''
    except TypeError:
        try:
            for x in item:
                break
        except TypeError:
            return False
        else:
            return True
    else:
        return False

def indices(L):
    res = []
    d = indexer([len(L)])
    g = iter(d)
    R = L[:]
    while R:
        res.append(g.next())
        x,R = R[0],R[1:]
        if issequence(x):
            R = x + R
            d.addlevel(len(x),-1)
    return res

def test():
    L = indexable(['aa',['bb',['cc','dd'],'ee'],'ff',['gg']])
    print L
    X = indices(L)
    for x in X:
        print "%-15s%-30s" %(x,L[x])

if __name__=='__main__':
    test()






More information about the Python-list mailing list