Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Pre-PEP: reverse iteration methods

Reply
Thread Tools

Pre-PEP: reverse iteration methods

 
 
Stephen Horne
Guest
Posts: n/a
 
      09-24-2003
On Wed, 24 Sep 2003 04:44:21 GMT, "Andrew Dalke"
<(E-Mail Removed)> wrote:

>-1 from me. 'backwards' looks to me like something which changes
>the list ordering in place, like what 'reverse' does. Or something
>which returns a new list but in reverse order. It's an adjective,
>when it should be a verb.


I disagree with this. IMO something that modifies a value in place
should be named using a verb (such as reverse, or sort, or update...).
Something that returns a value without modifying its parameters/object
should be named to describe what it returns - normally a noun or
adjective (such as globals, len, isinstance).

So if we had a sorting function that returns a sorted version of the
parameter without modifying its parameter, I'd want it to be called
'sorted' as opposed to the current in-place 'sort'.

Of course there are non-modifying functions that are named as verbs
(map, filter and reduce being particularly obvious), but that does
seems slightly wrong to me - though for the ones I've listed there is
basically an overriding convention (they are well known names).


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
 
 
 
Stephen Horne
Guest
Posts: n/a
 
      09-24-2003
On Wed, 24 Sep 2003 02:13:48 GMT, "Andrew Dalke"
<(E-Mail Removed)> wrote:

>> Frankly, I prefer the notion of a method.

>
>While I don't.


To me, the reason to use a method (or property) is simply that most
types cannot be efficiently 'backwardised'. For instance, iterators in
general would have to be buffered into a list an then the resulting
list iterated backwards. That could be useful, but the overhead is
sufficient that I think explicitly writing 'list (x).backward ()'
rather than 'x.backward ()' would be a good thing.

Having a method (or property) explicitly associates it with the
object/class being handled.


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
 
 
 
Stephen Horne
Guest
Posts: n/a
 
      09-24-2003
On Wed, 24 Sep 2003 04:44:21 GMT, "Andrew Dalke"
<(E-Mail Removed)> wrote:

>-1 from me. 'backwards' looks to me like something which changes
>the list ordering in place, like what 'reverse' does. Or something
>which returns a new list but in reverse order. It's an adjective,
>when it should be a verb.


I disagree with this. IMO something that modifies a value in place
should be named using a verb (such as reverse, or sort, or update...).
Something that returns a value without modifying its parameters/object
should be named to describe what it returns - normally a noun or
adjective (such as globals, len, isinstance).

So if we had a sorting function that returns a sorted version of the
parameter without modifying its parameter, I'd want it to be called
'sorted' as opposed to the current in-place 'sort'.

Of course there are non-modifying functions that are named as verbs
(map, filter and reduce being particularly obvious), but that does
seems slightly wrong to me - though for the ones I've listed there is
basically an overriding convention (they are well known names).


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
Stephen Horne
Guest
Posts: n/a
 
      09-24-2003
On Wed, 24 Sep 2003 02:13:48 GMT, "Andrew Dalke"
<(E-Mail Removed)> wrote:

>> Frankly, I prefer the notion of a method.

>
>While I don't.


To me, the reason to use a method (or property) is simply that most
types cannot be efficiently 'backwardised'. For instance, iterators in
general would have to be buffered into a list an then the resulting
list iterated backwards. That could be useful, but the overhead is
sufficient that I think explicitly writing 'list (x).backward ()'
rather than 'x.backward ()' would be a good thing.

Having a method (or property) explicitly associates it with the
object/class being handled.


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
=?ISO-8859-1?Q?Hannu_Kankaanp=E4=E4?=
Guest
Posts: n/a
 
      09-24-2003
"Andrew Dalke" <(E-Mail Removed)> wrote in message news:<w57cb.1289$(E-Mail Removed) link.net>...
> Sure. Then it'll given an exception. The implementation
> should turn around and raise the proper exception there
> instead of a "len doesn't exist" one.
>
> There's also a problem that len works on a dict but
> __getitem__(int) will only work if the dict stores 0->n-1
> as keys.



How about using a temporary sequence if __riter__ isn't defined?
It's slow, but would work with all non-infinite iterators that
don't have strange side effects (vast majority).


def riter(obj):
try:
rit = getattr(obj, "__riter__")
except AttributeError:
# assuming list has __riter__, the following could be:
# for x in riter(list(obj)):
# yield x
seq = list(obj)
n = len(seq)
while n != 0:
n -= 1
yield seq[n]
else:
for term in rit():
yield term

# reverse iteration of file
f = file('riter.py')
try:
for line in riter(f):
print line,
finally:
f.close()

# reverse iteration of a dictionary
for x in riter({'foo':1, 'bar':2}):
print x,


I changed it to use a shorter name as suggested by Reedy, to be similar
with rfind etc. I also prefer a function instead of a method, as the function
can provide (slow) default behaviour for iterators that don't explicitely
support reverse iteration.
 
Reply With Quote
 
sebastien
Guest
Posts: n/a
 
      09-24-2003
> PEP: 323
> Title: Add Reverse Iteration Methods
> Version: $Revision: 1.1 $


I don't need this often enough to want it as a method or a builtin
function.
But it would ne nice to have a function in the itertool module.

I would call it riter(), it should work on any sequence with len()
support or on any object wich define the __riter__ special method.

In practice, I mostly use reverse iteration when I most remove some
few objects on the sequence I'm itering to, so I have more neeed for a
renumerate() function:

for index, value in itertools.renumerate(sequence):
if not value:
del sequence(index)
 
Reply With Quote
 
Raymond Hettinger
Guest
Posts: n/a
 
      09-24-2003
[Raymond Hettinger]
> > for elem in seqn.iter_backwards():
> > print elem


[Stephen Horne]
> That is a pretty long name. Can we use the convention from itertools
> where an 'i' prefix is sufficient to suggest an iterator, giving
> 'ibackwards' or 'ireverse' or similar.


That sounds reasonable to me. I'll add that alternative to the PEP.

If the discussion on enumerate() is any indication, then the naming
discussion will be much more lively than on the idea itself. Perhaps,
Alex will once again be able to suggest a musically perfect, beautiful
Italian name.

BTW, if you think iter_backwards is long, then take a look at some
of the method names in the sets module.


> 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)?
Please show what a pure python version would look like
(taking UserList as an example).



> >* Should file objects be included? Implementing reverse iteration may not
> > be easy though it would be useful on occasion.

>
> IMO no - doing this essentially needs the whole file to be read into
> memory, in which case you may as well read the whole file into a list
> and then iterate the list backwards.


Oh, it could be done using seeks and whatnot;
however, the code might be grotesque.



> >* 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:

>>> mystr = 'abc'
>>> list(enumerate(mystr.iter_backwards()))

[(0, 'c'), (1, 'b'), (2, 'a')]

If you want the indices to match their original position, then you
would need something like:

>>> list(enumerate(mystr).iter_backwards())

[(2, 'c'), (1, 'b'), (0, 'a')]

The implementation would need to access both mystr.iterbackwards()
and mystr.__len__().

At first glance, this is a can of worms, a pandora's box,
a gordian knot, or some unnamed code smell unsuitable
for this mixed metaphor.



Raymond Hettinger



 
Reply With Quote
 
John Roth
Guest
Posts: n/a
 
      09-24-2003

"Stephen Horne" <$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote in
message news:(E-Mail Removed)...
> On Wed, 24 Sep 2003 00:30:31 GMT, "Raymond Hettinger"
> <(E-Mail Removed)> wrote:
>
> >Proposal
> >========
> >

>
> >* Should file objects be included? Implementing reverse iteration may

not
> > be easy though it would be useful on occasion.

>
> IMO no - doing this essentially needs the whole file to be read into
> memory, in which case you may as well read the whole file into a list
> and then iterate the list backwards.


Actually, it doesn't. It does require that the file be read into the
buffers backwards, but from there it's simply a matter of doing
a reverse scan for the line ending characters. The difficulty is that
the entire algorithm would have to be done in C, without any
significant help from the standard library.

John Roth
>
>
>
> --
> Steve Horne
>
> steve at ninereeds dot fsnet dot co dot uk



 
Reply With Quote
 
=?ISO-8859-1?Q?Hannu_Kankaanp=E4=E4?=
Guest
Posts: n/a
 
      09-24-2003
Stephen Horne <$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote in message news:<(E-Mail Removed)>. ..
> >* 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.


That's not the same:

>>> list(enumerate([10,11,12]))

[(0, 10), (1, 11), (2, 12)]
>>> list(enumerate([10,11,12].riter()))

[(0, 12), (1, 11), (2, 10)]
>>> list(enumerate([10,11,12]).riter())

[(2, 12), (1, 11), (0, 10)]

Indices would also be reversed.
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      09-24-2003
Raymond Hettinger wrote:

> If you want the indices to match their original position, then you
> would need something like:
>
> >>> list(enumerate(mystr).iter_backwards())

> [(2, 'c'), (1, 'b'), (0, 'a')]
>
> The implementation would need to access both mystr.iterbackwards()
> and mystr.__len__().
>
> At first glance, this is a can of worms, a pandora's box,
> a gordian knot, or some unnamed code smell unsuitable
> for this mixed metaphor.


You can count down starting at -1 for reverse enumeration and keep that can
of pandora's knots closed

The only drawback I see would be that the following behaviour might not be
what you expect:

>>> [(i, c, "uvwxyz"[i]) for i, c in reverse_enumerate("abc")]

[(-1, 'c', 'z'), (-2, 'b', 'y'), (-3, 'a', 'x')]
>>>


Peter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Struts - Problem with nested iteration or double iteration Rudi Java 5 10-01-2008 03:30 AM
PEP 322: Reverse Iteration (REVISED, please comment) Raymond Hettinger Python 31 11-06-2003 07:27 AM
PEP 322: Reverse Iteration (second revision, please comment) Raymond Hettinger Python 14 11-01-2003 05:51 PM
RE: PEP 322: Reverse Iteration (REVISED, please comment) Robert Brewer Python 1 10-29-2003 07:28 PM
Comment on PEP-0322: Reverse Iteration Methods Raymond Hettinger Python 59 09-29-2003 05:35 PM



Advertisments