iterators and views of lists

Anh Hai Trinh anh.hai.trinh at gmail.com
Sat Dec 19 12:04:25 EST 2009


On Dec 19, 5:47 am, Bearophile <bearophileH... at lycos.com> wrote:

> It seems you have missed my post, so here it is, more explicitly:
>
> http://www.boostcon.com/site-media/var/sphene/sphwiki/attachment/2009...


Interestingly, my `listagent` can be used as a lazy iterator and thus
using itertools we can compose them just like Andrei's `range`.

the stage:

  x = range(0, 20, 2); x
  [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

  y = range(10, 20); y
  [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

  z = [996, 758, 670, 236, 898, 337, 442, 452, 490, 547]

  from listagent import listagent
  import itertools

chain:

  sorted(itertools.chain(listagent(x)[::2], listagent(y)[-1:1:-2]))
  [0, 4, 8, 12, 13, 15, 16, 17, 19]

zip:

  sorted(itertools.izip(listagent(z)[1::3], listagent(x)[2::3]))
  [(452, 16), (758, 4), (898, 10)]

stride: slicing an agent returns another one, those lazy agents!

  python -m timeit -s'from listagent import listagent' 'list(listagent
(range(1000000))[1:-1:5][::7][10000:-10000:42])'
  10 loops, best of 3: 55.5 msec per loop

  python -m timeit 'range(1000000)[1:-1:5][::7][10000:-10000:42]'
  10 loops, best of 3: 280 msec per loop

radial: not implemented


`listagent` is implemented in pure Python, of course. If implemented
in C, there is surprisingly little difference between a slicing
`agent` like this, or a listiterator, since both will have to keep a
pointer to an memory index of in the original list: the listiterator
advances this pointer when we call next(), whereas the agent keeps a
pointer to the starting element of the slice and return basically
(PyObject *) *(p+(i*step)) on __getitem__[i]. Mutability is a just
matter of exposing this pointer to Python code in a nice way.

----aht



More information about the Python-list mailing list