[Python-ideas] lazy list

Alexander Atkins alexander at tutorfair.com
Thu May 14 17:44:19 CEST 2015


On 14 May 2015 at 16:24, Steven D'Aprano <steve at pearwood.info> wrote:

> What sort of uses? Can you give some examples?
>
> I'm having trouble thinking of a situation where I might use something
> like that. If I want random access, I'd use a list, or a computed
> sequence like (x)range. I don't think I would want something which acts
> like a generator but quietly holds onto all the items it has seen
> before, whether I need them or not.
>

Yes: you might want random access into an infinite sequence, where you
can't be sure how many values you'll need at the start but you will want to
reuse or refer back to earlier values later, and you can't be sure which
ones you'll need.  If you know you only want each value once, then you
should stick with a generator.  For example, you might need to read from a
network stream or stdin, and the point where you stop reading might depend
on content, but you might need to refer back to earlier items read, where
the index of the item you need is determined at run-time.

In my particular case, I was writing a program that reads from a large, but
finite sequence, where I usually only need the first few items, but the
maximum index that I need is determined at runtime,* and it was taking too
long to process the whole list before starting.  So I wrote a generator for
the sequence instead, and used my LazyList wrapper to get random access on
it.

* Actually, it's not determined at runtime, but it is determined by another
part of the program outside of the function I was writing.



> A slice is just a subsequence of indexed values. If you can index it,
> you should be able to slice it.
>
> assert spam[start:end:step] == [spam[i] for i in range(start, end, step)]
>

What I was trying to do was to create a slice without losing the laziness.
For example, in my implementation you can take a slice like foo[start:]
from an infinite sequence without causing problems.  I haven't quite done
it right, because I've returned an iterator instead of another LazyList
object, but I could fix it up.  I discuss this a bit more in the example
program given in the repository.


Python draws a lot from Haskell, especially the itertools module.  Almost
everything that's cool about lazy evaluation in Haskell is in Python
somewhere.  But Haskell has neither the list type that Python has, nor the
generator type: it only has lazy linked lists, which have to serve for
both.  So it seemed to me to be an obvious omission for those few cases
where that's really what you want.  But I can totally believe that if
nobody's thought of this so far then it's probably not commonly useful.

--
*J Alexander D Atkins*

Personal:  <https://plus.google.com/105921567919327579489/about> – 07963
237265

Work:  <https://www.tutorfair.com/> – 020 3322 4748
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150514/e104c669/attachment.html>


More information about the Python-ideas mailing list