python/nondist/peps pep-0322.txt,1.9,1.10
![](https://secure.gravatar.com/avatar/7b43f399ad17706bee01be8cd20165b0.jpg?s=120&d=mm&r=g)
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.
participants (1)
-
rhettingerīŧ users.sourceforge.net