Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #50450 > unrolled thread

xslice idea | a generator slice

Started byRussel Walker <russ.pobox@gmail.com>
First post2013-07-11 07:52 -0700
Last post2013-07-11 10:16 -0600
Articles 9 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  xslice idea | a generator slice Russel Walker <russ.pobox@gmail.com> - 2013-07-11 07:52 -0700
    Re: xslice idea | a generator slice Russel Walker <russ.pobox@gmail.com> - 2013-07-11 07:54 -0700
      Re: xslice idea | a generator slice Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-07-11 16:14 +0100
        Re: xslice idea | a generator slice Russel Walker <russ.pobox@gmail.com> - 2013-07-11 09:21 -0700
          Re: xslice idea | a generator slice Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-07-11 17:34 +0100
          Re: xslice idea | a generator slice Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-11 12:00 -0600
          Re: xslice idea | a generator slice Fábio Santos <fabiosantosart@gmail.com> - 2013-07-11 20:58 +0100
          Re: xslice idea | a generator slice Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-11 15:02 -0600
    Re: xslice idea | a generator slice Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-11 10:16 -0600

#50450 — xslice idea | a generator slice

FromRussel Walker <russ.pobox@gmail.com>
Date2013-07-11 07:52 -0700
Subjectxslice idea | a generator slice
Message-ID<4a81b6a6-023e-4d47-9bd0-bbc0516caf6b@googlegroups.com>
Just some dribble, nothing major.

I like using slices but I also noticed that a slice expression returns a new sequence.

I sometimes find myself using them in a for loop like this:


seq = range(10)
for even in seq[::2]:
    print even


(That's just for an example) But wouldn't it be a bit of a waste if the slice expression returns a whole new list just when all you want to do in this case is iterate over it once?

I suppose you could get around that will a little more code like:


seq = range(10)
for x in xrange(0, len(seq), 2):
    print seq[x]


But it would be nice there was a way to iterate over a 'slice' of sorts, that would act as a generator.

So I tried my handle at a little class called xslice (the x from xrange to indicate its a generator (although I'm not sure if that's technically correct)).

With it, instead of the above example you can do:


seq = range(10)
for even in xslice(seq, 0, len(seq), 2):
    print even


It would be more or less like using xrange. I know the syntax is not that much of an improvement over just using exrange and retrieving items by index, but it's the concept I'm looking at.

Do you think this or something like be a builtin in the future?

[toc] | [next] | [standalone]


#50451

FromRussel Walker <russ.pobox@gmail.com>
Date2013-07-11 07:54 -0700
Message-ID<c087829a-8e30-4f50-afb9-d28a779932e3@googlegroups.com>
In reply to#50450
...oh and here is the class I made for it.

class xslice(object):
    '''
    xslice(seq, start, stop, step) -> generator slice
    '''

    def __init__(self, seq, *stop):
        if len(stop) > 3:
            raise TypeError("xslice takes at most 4 arguments")
        elif len(stop) < 0:
            raise TypeError("xslice requires atleast 2 arguments")
        else:
            start, stop, step = (((0,) + stop[:2])[-2:] +  # start, stop
                                 (stop[2:] + (1,))[:1])    # step
            stop = min(stop, len(seq))
            self._ind = iter(xrange(start, stop, step))
            self._seq = seq

    def __iter__(self):
        return self

    def next(self):
        return self._seq[self._ind.next()]



Although now that I think about it, it probably should've just been a simple generator function.

[toc] | [prev] | [next] | [standalone]


#50453

FromOscar Benjamin <oscar.j.benjamin@gmail.com>
Date2013-07-11 16:14 +0100
Message-ID<mailman.4590.1373555714.3114.python-list@python.org>
In reply to#50451
On 11 July 2013 15:54, Russel Walker <russ.pobox@gmail.com> wrote:
> ...oh and here is the class I made for it.
>
> class xslice(object):
>     '''
>     xslice(seq, start, stop, step) -> generator slice
>     '''
>
>     def __init__(self, seq, *stop):

Wouldn't it be better if it has the same signature(s) as itertools.islice?

>         if len(stop) > 3:
>             raise TypeError("xslice takes at most 4 arguments")
>         elif len(stop) < 0:

How would len(stop) be negative?

>             raise TypeError("xslice requires atleast 2 arguments")
>         else:
>             start, stop, step = (((0,) + stop[:2])[-2:] +  # start, stop
>                                  (stop[2:] + (1,))[:1])    # step
>             stop = min(stop, len(seq))
>             self._ind = iter(xrange(start, stop, step))
>             self._seq = seq
>
>     def __iter__(self):
>         return self
>
>     def next(self):
>         return self._seq[self._ind.next()]
>
>
>
> Although now that I think about it, it probably should've just been a simple generator function.

Or you can use itertools.imap:

def xslice(sequence, start_or_stop, *args):
    indices = xrange(*slice(start_or_stop, *args).indices(len(sequence)))
    return imap(sequence.__getitem__, indices)


Oscar

[toc] | [prev] | [next] | [standalone]


#50465

FromRussel Walker <russ.pobox@gmail.com>
Date2013-07-11 09:21 -0700
Message-ID<56736add-f372-4245-9f50-076b3d44bb00@googlegroups.com>
In reply to#50453
> >     def __init__(self, seq, *stop):
> 
> 
> 
> Wouldn't it be better if it has the same signature(s) as itertools.islice?

That's actually what I was going for, except I was modeling it after range, but that was the only way I knew to implement it.


> >         if len(stop) > 3:
> 
> >             raise TypeError("xslice takes at most 4 arguments")
> 
> >         elif len(stop) < 0:
> 
> 
> 
> How would len(stop) be negative?


Yes, that should've been len(stop) < 1.


> Or you can use itertools.imap:
> 
> 
> 
> def xslice(sequence, start_or_stop, *args):
> 
>     indices = xrange(*slice(start_or_stop, *args).indices(len(sequence)))
> 
>     return imap(sequence.__getitem__, indices)
> 
> 
> 
> 
> 
> Oscar


I like the way you did that with imap, although I still like my parameter implementation.

To confess, this is the second time I've made the mistake of trying to implement generator like functionality of a builtin when there already is on in itertools. Need to start studying that module abit more I think. I'm looking at the docs now and I see there are actually a couple of isomethings().

[toc] | [prev] | [next] | [standalone]


#50466

FromOscar Benjamin <oscar.j.benjamin@gmail.com>
Date2013-07-11 17:34 +0100
Message-ID<mailman.4597.1373560496.3114.python-list@python.org>
In reply to#50465
On 11 July 2013 17:21, Russel Walker <russ.pobox@gmail.com> wrote:
> To confess, this is the second time I've made the mistake of trying to implement generator like functionality of a builtin when there already is on in itertools. Need to start studying that module abit more I think. I'm looking at the docs now and I see there are actually a couple of isomethings().

Your xslice (or mine) would still be better than islice when the step
size is large; islice has to iterate over all the skipped elements
which could be wasteful if the input is indexable. Also islice doesn't
support negative values for start, stop or step which xslice does.

[toc] | [prev] | [next] | [standalone]


#50470

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-07-11 12:00 -0600
Message-ID<mailman.4599.1373565668.3114.python-list@python.org>
In reply to#50465
On Thu, Jul 11, 2013 at 10:34 AM, Oscar Benjamin
<oscar.j.benjamin@gmail.com> wrote:
> On 11 July 2013 17:21, Russel Walker <russ.pobox@gmail.com> wrote:
>> To confess, this is the second time I've made the mistake of trying to implement generator like functionality of a builtin when there already is on in itertools. Need to start studying that module abit more I think. I'm looking at the docs now and I see there are actually a couple of isomethings().
>
> Your xslice (or mine) would still be better than islice when the step
> size is large; islice has to iterate over all the skipped elements
> which could be wasteful if the input is indexable. Also islice doesn't
> support negative values for start, stop or step which xslice does.

Ah, that's an interesting point.  Of course the corollary to that is
that xslice requires a sequence, not just an iterable.

[toc] | [prev] | [next] | [standalone]


#50475

FromFábio Santos <fabiosantosart@gmail.com>
Date2013-07-11 20:58 +0100
Message-ID<mailman.4601.1373572738.3114.python-list@python.org>
In reply to#50465

[Multipart message — attachments visible in raw view] — view raw

On 11 Jul 2013 17:38, "Oscar Benjamin" <oscar.j.benjamin@gmail.com> wrote:
>
> On 11 July 2013 17:21, Russel Walker <russ.pobox@gmail.com> wrote:
> > To confess, this is the second time I've made the mistake of trying to
implement generator like functionality of a builtin when there already is
on in itertools. Need to start studying that module abit more I think. I'm
looking at the docs now and I see there are actually a couple of
isomethings().
>
> Your xslice (or mine) would still be better than islice when the step
> size is large; islice has to iterate over all the skipped elements
> which could be wasteful if the input is indexable. Also islice doesn't
> support negative values for start, stop or step which xslice does.

Isn't all of itertools implemented in C? If we are not using a python-level
and not-so-fast __getitem__ I would wager the C version is a lot faster.

And if the input is indexable could I assume that it is not too large to
have around in memory and thus any speed increase in looping over it would
be tiny?

[toc] | [prev] | [next] | [standalone]


#50476

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-07-11 15:02 -0600
Message-ID<mailman.4602.1373576607.3114.python-list@python.org>
In reply to#50465
On Thu, Jul 11, 2013 at 1:58 PM, Fábio Santos <fabiosantosart@gmail.com> wrote:
> Isn't all of itertools implemented in C? If we are not using a python-level
> and not-so-fast __getitem__ I would wager the C version is a lot faster.
>
> And if the input is indexable could I assume that it is not too large to
> have around in memory and thus any speed increase in looping over it would
> be tiny?

Oscar's version which is an imap of an xrange is also effectively
implemented in C.  Only the setup is in Python.

[toc] | [prev] | [next] | [standalone]


#50464

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-07-11 10:16 -0600
Message-ID<mailman.4596.1373559441.3114.python-list@python.org>
In reply to#50450
On Thu, Jul 11, 2013 at 8:52 AM, Russel Walker <russ.pobox@gmail.com> wrote:
> Just some dribble, nothing major.
>
> I like using slices but I also noticed that a slice expression returns a new sequence.
>
> I sometimes find myself using them in a for loop like this:
>
>
> seq = range(10)
> for even in seq[::2]:
>     print even
>
>
> (That's just for an example) But wouldn't it be a bit of a waste if the slice expression returns a whole new list just when all you want to do in this case is iterate over it once?
>
> I suppose you could get around that will a little more code like:
>
>
> seq = range(10)
> for x in xrange(0, len(seq), 2):
>     print seq[x]
>
>
> But it would be nice there was a way to iterate over a 'slice' of sorts, that would act as a generator.

That would be the itertools.islice function.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web