[Python-checkins] python/nondist/peps pep-0322.txt,1.9,1.10

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Thu Oct 30 02:41:22 EST 2003


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1:/tmp/cvs-serv29134

Modified Files:
	pep-0322.txt 
Log Message:
Update PEP based on discussion on comp.lang.python:

* reversed() is being preferred to ireverse() as the best name.

* the sample implementation now shows a check for a custom reverse
  method and a guard against being applied to a mapping.

* added sample output for enumerate.__reversed__ to show an example of
  how a custom reverse method would work

* explained why the function is proposed as a builtin.

* expanded a couple for the real world use cases to show what the
  replacement code would look like.

* improved markup so that the function names get italicized.



Index: pep-0322.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0322.txt,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** pep-0322.txt	28 Oct 2003 22:39:22 -0000	1.9
--- pep-0322.txt	30 Oct 2003 07:41:20 -0000	1.10
***************
*** 47,51 ****
  ========
  
! Add a builtin function called *ireverse()* that makes a reverse
  iterator over sequence objects that support __getitem__() and
  __len__().
--- 47,51 ----
  ========
  
! Add a builtin function called *reversed()* that makes a reverse
  iterator over sequence objects that support __getitem__() and
  __len__().
***************
*** 53,71 ****
  The above examples then simplify to::
  
!     for i in ireverse(xrange(n)):
          print seqn[i]
  
  ::
  
!     for elem in ireverse(seqn):
          print elem
  
  The core idea is that the clearest, least error-prone way of specifying
  reverse iteration is to specify it in a forward direction and then say
! *ireverse*.
  
  The implementation could be as simple as::
  
!     def ireverse(x):
          i = len(x)
          while i > 0:
--- 53,77 ----
  The above examples then simplify to::
  
!     for i in reversed(xrange(n)):
          print seqn[i]
  
  ::
  
!     for elem in reversed(seqn):
          print elem
  
  The core idea is that the clearest, least error-prone way of specifying
  reverse iteration is to specify it in a forward direction and then say
! *reversed*.
  
  The implementation could be as simple as::
  
!     def reversed(x):
!         try:
!             return x.__reversed__()
!         except AttributeError:
!             pass
!         if hasattr(x, "has_key"):
!             raise ValueError("mappings do not support reverse iteration")
          i = len(x)
          while i > 0:
***************
*** 73,79 ****
              yield x[i]
  
- If *x* is a mapping, the implementation should return a ValueError with
- a message noting that reverse iteration is undefined for mappings.
- 
  No language syntax changes are needed.  The proposal is fully backwards
  compatible.
--- 79,82 ----
***************
*** 83,87 ****
  ========================
  
! * *backwards* -- more pithy, less explicit
  * *inreverse* -- no one seems to like this one except me
  
--- 86,90 ----
  ========================
  
! * *ireverse* -- uses the itertools naming convention
  * *inreverse* -- no one seems to like this one except me
  
***************
*** 93,105 ****
  ==============
  
! Objects may optionally provide an *__ireverse__* method that returns
  a custom reverse iterator.
  
! This allows reverse() to be applied to objects that do not have 
  __getitem__() and __len__() but still have some useful way of
  providing reverse iteration.
  
! Using this protocol, enumerate() can be extended to support reversal
! whenever the underlying iterator supports it also.
  
  
--- 96,111 ----
  ==============
  
! Objects may optionally provide a *__reversed__* method that returns
  a custom reverse iterator.
  
! This allows *reverse()* to be applied to objects that do not have 
  __getitem__() and __len__() but still have some useful way of
  providing reverse iteration.
  
! For example, using this protocol, *enumerate()* can be extended to 
! support reversal whenever the underlying iterator supports it also::
! 
!     >>> list(reversed(enumerate("abc")))
!     [(2, 'c'), (1, 'b'), (0, 'a')]
  
  
***************
*** 124,127 ****
--- 130,135 ----
    possible; however, that would complicate the rest of the heap code
    which iterates over the underlying list in the opposite direction.
+   The replacement code ``for i in reversed(xrange(n//2))`` makes
+   clear the range covered and how many iterations it takes.
  
  * mhlib.test() uses::
***************
*** 144,148 ****
    be run in a forward direction but is less intuitive and rarely
    presented that way in literature.  The replacement code
!   ``for i in ireverse(xrange(1, len(x)))`` is much easier
    to verify visually.
  
--- 152,156 ----
    be run in a forward direction but is less intuitive and rarely
    presented that way in literature.  The replacement code
!   ``for i in reversed(xrange(1, len(x)))`` is much easier
    to verify visually.
  
***************
*** 161,175 ****
  
  A simpler, but limited alternative is to create a builtin that takes
! the same arguments as range() but returns a reverse iterator over the
! range.  The idea is that much of the benefit of ireverse() comes
  reducing the intellectual effort it takes to express the arguments for
  [x]range() when going backwards.  A good name is needed for this
! alternative -- revrange() is cleanest so far.
  
  
! Rejected Alternative
! ====================
  
! Several variants were submitted that attempted to apply ireverse()
  to all iterables by running the iterable to completion, saving the
  results, and then returning a reverse iterator over the results.
--- 169,183 ----
  
  A simpler, but limited alternative is to create a builtin that takes
! the same arguments as *range()* but returns a reverse iterator over the
! range.  The idea is that much of the benefit of *reversed()* comes
  reducing the intellectual effort it takes to express the arguments for
  [x]range() when going backwards.  A good name is needed for this
! alternative -- *revrange()* is cleanest so far.
  
  
! Rejected Alternatives
! =====================
  
! Several variants were submitted that attempted to apply *reversed()*
  to all iterables by running the iterable to completion, saving the
  results, and then returning a reverse iterator over the results.
***************
*** 178,181 ****
--- 186,197 ----
  in the first place.  Also, a small disaster ensues if the underlying
  iterator is infinite.
+ 
+ Putting the function in another module or attaching it to a type object
+ is not being considered.  Like its cousins, *zip()* and *enumerate()*,
+ the function needs to be directly accessible in daily programming.  Each
+ solves a basic looping problem:  lock-step iteration, loop counting, and
+ reverse iteration.  Requiring some form of dotted access would interfere
+ with their simplicity, daily utility, and accessibility.  They are core
+ looping constructs, independent of any one application domain.
  
  





More information about the Python-checkins mailing list