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


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

Re: learning to use iterators

Started byVito De Tullio <vito.detullio@gmail.com>
First post2014-12-24 16:12 +0100
Last post2014-12-25 11:34 +0100
Articles 4 — 4 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: learning to use iterators Vito De Tullio <vito.detullio@gmail.com> - 2014-12-24 16:12 +0100
    Re: learning to use iterators Rustom Mody <rustompmody@gmail.com> - 2014-12-24 12:34 -0800
      Re: learning to use iterators Ian Kelly <ian.g.kelly@gmail.com> - 2014-12-24 22:36 -0700
      Re: learning to use iterators Peter Otten <__peter__@web.de> - 2014-12-25 11:34 +0100

#82892 — Re: learning to use iterators

FromVito De Tullio <vito.detullio@gmail.com>
Date2014-12-24 16:12 +0100
SubjectRe: learning to use iterators
Message-ID<mailman.17185.1419433939.18130.python-list@python.org>
Seb wrote:

>>>> def n_grams(a, n):
> ...     z = (islice(a, i, None) for i in range(n))
> ...     return zip(*z)
> ...
> 
> I'm impressed at how succinctly this islice helps to build a list of
> tuples with indices for all the required windows.

If you want it succinctly, there is this variation on the theme:

n_grams = lambda a, n: zip(*(a[i:] for i in range(n)))


-- 
By ZeD

[toc] | [next] | [standalone]


#82903

FromRustom Mody <rustompmody@gmail.com>
Date2014-12-24 12:34 -0800
Message-ID<8a840698-a3be-4889-9ddd-756a553e6f48@googlegroups.com>
In reply to#82892
On Wednesday, December 24, 2014 8:42:32 PM UTC+5:30, Vito De Tullio wrote:
> Seb wrote:
> 
> >>>> def n_grams(a, n):
> > ...     z = (islice(a, i, None) for i in range(n))
> > ...     return zip(*z)
> > ...
> > 
> > I'm impressed at how succinctly this islice helps to build a list of
> > tuples with indices for all the required windows.
> 
> If you want it succinctly, there is this variation on the theme:
> 
> n_grams = lambda a, n: zip(*(a[i:] for i in range(n)))

+3 but -1
+1 for using an inlining the z
+1 for showing that the * can take any expression [I did not know that]
+1 for the slice in succinct form

-1 for the lambda -- quite unnecessary and a red-herring

If squeezing out the last char is the idea

n_grams = lambda a, n: zip(*(a[i:] for i in range(n)))

is same as

def n_grams(a,n):return zip(*(a[i:]for i in range(n)))

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


#82910

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-12-24 22:36 -0700
Message-ID<mailman.17196.1419485832.18130.python-list@python.org>
In reply to#82903

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

On Wed, Dec 24, 2014 at 1:34 PM, Rustom Mody <rustompmody@gmail.com> wrote:
> +1 for the slice in succinct form

Not only more succinct but also more correct. The purpose of islice is to
slice arbitrary iterables as opposed to just sequences. But this function
requires a reentrant iterable anyway and returns garbage if you pass it an
iterator, so there's really no reason for it here. The version using slice
notation on the other hand will raise a TypeError if you pass it an
iterator or anything else that can't be sliced, which is preferable to
silently returning incorrect results.

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


#82912

FromPeter Otten <__peter__@web.de>
Date2014-12-25 11:34 +0100
Message-ID<mailman.17198.1419503693.18130.python-list@python.org>
In reply to#82903
Ian Kelly wrote:

> On Wed, Dec 24, 2014 at 1:34 PM, Rustom Mody <rustompmody@gmail.com>
> wrote:
>> +1 for the slice in succinct form
> 
> Not only more succinct but also more correct. The purpose of islice is to
> slice arbitrary iterables as opposed to just sequences. But this function
> requires a reentrant iterable anyway and returns garbage if you pass it an
> iterator, so there's really no reason for it here. The version using slice
> notation on the other hand will raise a TypeError if you pass it an
> iterator or anything else that can't be sliced, which is preferable to
> silently returning incorrect results.

The natural remedy to that problem is of course itertools.tee():

>>> from itertools import islice, tee
>>> def n_grams(items, n):
...     z = (islice(it, start, None) for start, it in enumerate(tee(items, n)))
...     return zip(*z)
... 
>>> for item in n_grams(iter("abcde"), 3):
...     print("".join(item))
... 
abc
bcd
cde
>>> 

[toc] | [prev] | [standalone]


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


csiph-web