slice notation as values?

Antoon Pardon apardon at forel.vub.ac.be
Mon Dec 12 06:25:55 EST 2005


Op 2005-12-12, Bengt Richter schreef <bokr at oz.net>:
> On 12 Dec 2005 08:34:37 GMT, Antoon Pardon <apardon at forel.vub.ac.be> wrote:
>
>>Op 2005-12-10, Devan L schreef <devlai at gmail.com>:
>>>
>>> Antoon Pardon wrote:
>>>> On 2005-12-10, Duncan Booth <duncan.booth at invalid.invalid> wrote:
>>> [snip]
>>>> >> I also think that other functions could benefit. For instance suppose
>>>> >> you want to iterate over every second element in a list. Sure you
>>>> >> can use an extended slice or use some kind of while. But why not
>>>> >> extend enumerate to include an optional slice parameter, so you could
>>>> >> do it as follows:
>>>> >>
>>>> >>   for el in enumerate(lst,::2)
>
> If you are willing to use square brackets, you can spell it

Hmm, I have to think about that.

> >>> for el in enoomerate[lst, ::2]: print el,
>
> (see below ;-)
>
>> [ ... ]

> Just for you ;-)

Thank you.

> >>> import itertools
> >>> class enoomerate(object):
>  ...     def __getitem__(self, seq):
>  ...         if isinstance(seq, tuple):
>  ...             seq, slc = seq
>  ...         else:
>  ...             slc = slice(None)
>  ...         if not isinstance(slc, slice): slc = slice(None, slc)
>  ...         return itertools.islice(enumerate(seq), slc.start or 0, slc.stop, slc.step or 1)
>  ...
> >>> enoomerate = enoomerate()
> >>>
> >>> import string
> >>> lst = list(string.ascii_lowercase) # legit list, though could use the string
> >>> for el in enoomerate[lst, ::2]: print el,

I am wondering a bit. Could this be turned into a decorator?

I don't have much experience with decorators, so I'll have to
think this through for a wgile. The idea would be a class
to be used as decorator that would turn a function returning
an iterator in a slicable iterator. Something like the following
maybe:

class SliceIterator(object):

    def __init__(self,func):
        self.func = func
  
    def __getitem__(self, args):
        if isinstance(args, tuple)
            return self.func(*args)
        else:
            return self.func(args)
  
    def __iter__(self):
        return self.func(slice(None, None, None))

I could then write something like:

    @SliceIterator
    def srange(sl):
        v = sl.stop
        while v < sl.start:
            yield v
            v += sl.step


And use it as:

     for i in srange[23:67:3]:
         ...

Hmm, I have to play with this a bit. Thanks for the idea.

-- 
Antoon Pardon



More information about the Python-list mailing list