Pre-PEP: reverse iteration methods

Stephen Horne $$$$$$$$$$$$$$$$$ at $$$$$$$$$$$$$$$$$$$$.co.uk
Thu Sep 25 19:40:25 CEST 2003


On Wed, 24 Sep 2003 09:57:18 GMT, "Raymond Hettinger"
<vze4rx4y at verizon.net> wrote:

>> Second, I'm not quite ready to drop my property idea ;-)
>>
>> An advantage is that the object returned by the property can sensibly
>> support more than just iteration - e.g. slicing (as touched on in the
>> PEP284 thread). So for instance...
>>
>> >>> x = range(10)
>> >>> list(x.backward)
>> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>
>I'm not clear on the details of what you're proposing.  What is
>type(x.backward)?

Some made-up proxy class that understands that certain operations will
work as if the list was reversed.

For integer lists, I'd use much the same thing but on the
set-of-all-integers object I proposed in the earlier thread. So I
could write...

  for i in integers.backwards [:10] :
    print i

...to do the same as your...

  for i in xrange (10).iter_backwards () :
    print i

...though I'm also having this idea about using the 'int' type object
to implement these again. It makes a certain sense for type names to
also act as abstract sets of possible values. For typechecking
purposes, for instance, it might be nice to be able to write...

  if x in float :
    do stuff with float value

Of course that's a long way from compelling given that we already have
the isinstance function, but what is attracting me is that these two
ideas...

  1.  Provide objects (or extend the type name objects) to provide
      the abstraction of a set of values of that type, implementing
      whatever operations are practical and useful for that
      abstraction.

  2.  Provide properties of objects (including that abstract set of
      integers) which act as proxies for the object, but providing
      an modified view of that object (including a backward view of a
      sequence object, but possibly other things too).

...seem to provide, either alone or in combination, natural solutions
to several problems. For instance, you don't just get the ability to
loop through a range of integers backwards...

  for i in integers.ibackwards [:50] :

But equally the ability to iterate through a sequence backwards...

  for i in x.ibackwards [:50] :

And basically you are doing the same thing in each case - its just
that the first example slices an abstract sequence as opposed to one
that is physically held in memory.

>Please show what a pure python version would look like
>(taking UserList as an example).

I didn't use UserList, but I did post example code in the "Comment on
PEP-0322: Reverse Iteration Methods" thread. I wasn't so keen in that
post, but I seem to like the idea again now.

>> >* Should enumerate() be included?  It would only provide reverse iteration
>> >  whenever the underlying sequence supported it.
>>
>> Why not...
>>
>>   for i, j in enumerate (listname.iter_backwards ()) :
>>
>> in other words, as enumerate can handle the already-reversed
>> sequence/iteration, I don't see the point.
>
>The point is that enumerate will starting numbering from zero
>for the last item:

Yes - I wasn't thinking straight, sorry about that. Just to put a
thought in based on those two ideas above, though, how about...

>>> x=["a", "b", "c"]
>>> print x.enumerated
[(0, "a"), (1, "b"), (2, "c")]
>>> print x.backwards.enumerated
[(0, "c"), (1, "b"), (2, "c")]
>>> print x.enumerated.backwards
[(2, "c"), (1, "b"), (0, "c")]

'enumerated' need not create the list or iterator immediately - again,
it returns a proxy which implements the modified behaviour. Having a
proxy to a proxy gives IMO quite a neat solution.


-- 
Steve Horne

steve at ninereeds dot fsnet dot co dot uk




More information about the Python-list mailing list