Arithmetic sequences in Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marc 'BlackJack' Rintsch

    #16
    Re: Arithmetic sequences in Python

    In <dqgpcm$eah$1@r eader2.panix.co m>, Roy Smith wrote:
    [color=blue]
    > Alex Martelli <aleax@mail.com cast.net> wrote:[color=green]
    >>Agreed. *IF* we truly needed an occasional "up to X *INCLUDED*"
    >>sequence, it should be in a syntax that can't FAIL to be noticed, such
    >>as range(X, endincluded=Tru e).[/color]
    >
    > How about...
    >
    > for i in (0..x]:
    > blah[/color]

    That would break most editors "highlight matching brace" functionality.

    Ciao,
    Marc 'BlackJack' Rintsch

    Comment

    • Szabolcs Nagy

      #17
      Re: Arithmetic sequences in Python

      i would love to see a nice, clear syntax instead of
      for i in xrange(start, stop, step): ...

      because xrange is ugly and iteration over int sequences are important.
      we don't need a range() alternative ( [0:10] or [0..10] )
      (because no one would ever use range() if there were a nice
      integer-for-loop)

      there was a proposal (http://www.python.org/peps/pep-0284.html):
      for start <= i < stop: ...
      but in this way you cannot specify the step parameter and it has some
      problems when used in list comprehension.

      pep 204 like syntax would be:
      for i in (start:stop:ste p): ...
      it is much nicer than xrange, but probably it has some inconsistency
      with slicing
      (eg (:3)=xrange(3), (-3:)=itertools.c ount(-3), (:-3)=?, (3::-1)=? )

      your .. approach:
      for i in (start, start+step .. stop): ...
      here start written down twice if it's referred by a name (and if start
      is a function call it's evaluated twice)
      imho without a step it looks nice:
      for i in (start .. stop): ...
      but a new syntax would be good only if it can entirely replace the old
      one (which then can be made deprecated).

      Comment

      • Paul Rubin

        #18
        Re: Arithmetic sequences in Python

        aleax@mail.comc ast.net (Alex Martelli) writes:[color=blue][color=green]
        > > Oh come on, [5,4,..0] is much easier to read than range(5,-1,-1).[/color]
        >
        > But not easier than reversed(range( 6))[/color]

        Heh, I like that, and reversed(xrange (6)) appears to do the right
        thing too. I didn't know about __reversed__ before.
        [color=blue]
        > [[the 5 in one of the two
        > expressions in your sentence has to be an offbyone;-)]][/color]

        Are you sure? I could easily be missing something, since it's easy
        to be offbyone with this stuff, but when I try it I get:

        Python 2.4.1 (#1, May 16 2005, 15:19:29)
        [GCC 4.0.0 20050512 (Red Hat 4.0.0-5)] on linux2
        Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
        >>> range(5,-1,-1)[/color][/color][/color]
        [5, 4, 3, 2, 1, 0][color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        and (skipping the ascii art banner):

        Hugs 98: Based on the Haskell 98 standard
        Haskell 98 mode: Restart with command line option -98 to enable extensions
        Type :? for help
        Hugs.Base> [5,4..0]
        [5,4,3,2,1,0]
        Hugs.Base>

        which is equivalent. (Of course, having to use 6 instead of 5 in
        the range(...) version invites an offbyone error).

        Comment

        • Paul Rubin

          #19
          Re: Arithmetic sequences in Python

          Xavier Morel <xavier.morel@m asklinn.net> writes:[color=blue]
          > The only thing that bothers me about the initial proposal is that
          > there would not, in fact, be any "range object", but merely a
          > syntactic sugar for list/generator creation.[/color]

          Well, it could create something like an xrange. Maybe that's preferable.
          [color=blue]
          > Not that I really mind it, but, well, syntactic sugar for the
          > purpose of syntactic sugar really doesn't bring much to the table.[/color]

          I don't think this is a valid objection. Python is already full of
          syntactic sugar like indentation-based block structure, infix
          operators, statements with keyword-dependent syntax, etc. It's that
          very sugar that attracts programmers to Python away from comparatively
          sugarless languages like Scheme. Indeed, Python is considered by many
          to be a sweet language to program in, and they mean that in a nice
          way.

          If you want, you can think of it as "flavor" rather than "sugar". We
          aren't after syntactic minimalism or we'd be using Scheme. The
          criterion for adding something like this to Python should be whether
          makes the language taste better or not.

          Comment

          • Gregory Petrosyan

            #20
            Re: Arithmetic sequences in Python

            Thanks for your replies. So, some problems and possible solutions:

            1) [f(n), f(n)-1 .. 0] can be easily catched by interpreter, and f(n)
            can be evaluated only once.

            2) if you need right border excluded, I think [0 .. n) is very clear
            (and consistent with mathematics). And about brakets highlighting... Do
            you _really_ need it in this expression? By the way, Python
            editors/ide's can be easily extended to support this syntax, and even
            to color brakets in [0 .. n) in different colors (so, it'll be very
            clear if border is included or not).
            But as for me, [0 .. n-1] is better because it looks more like ordinary
            list, and we would have no problems on creating generators with
            excluded border.

            3) Of course, in some cases 'range' is more readable. As for your
            examples:

            [0,..9] versus range(10)
            [55, ...73] versus range(55, 74)
            [1, 3, ..len(mystr)] versus range(1, len(mystr)+1, 2)
            [55, 65, 295] versus range(55, 296, 10)

            a) you use "magic" 10 here...
            [0 .. 10) or [0 .. 9] are IMO at least as nice as range(10). And what
            about
            [1 .. 10] and range(1, 11)? ;-)

            b) [55 .. 73] vs range(55, 74)? IMO first is more readable. And you
            actually can see what is the last value, while in "range" you think
            something like: "if 74 is written here, then last value is 74-1 = 73"

            c) [1, 3 .. len(mystr)] vs range(1, len(mystr)+1, 2). As for me, I
            should think for 2-3 seconds before I understand what range(1,
            len(mystr)+1, 2) stands for :-)
            And [1, 3 .. len(mystr)] is _obvious_ for almost everybody.

            d) why you wrote '296' in range? Maybe, because you are really
            experienced programmer, and you can automatically transform 295 -> 296
            (because you _know_ the behaviour of range function). But if your task
            is simply to iterate through sequence like n1, n2, n3, ... n(X-1), nX,
            then [n1 .. nX] looks more natural, isn't it?

            4) Proposed syntax can be easily extended to support chars (or any
            other enumeration). (Maybe, without _implied_ :-) step parameter):

            ['a' .. 'd'] -> ['a','b','c','d'] (let it be a list for consistency)
            ('x' .. 'z') -> generator that yields 'x', 'y' and 'z' :-)
            ('a' ..) -> generator that yields english alphabet

            Conclusion:
            - I don't want to remove 'range' function from use completely. Feel
            free to use it ;-)
            - The only idea behind my proposal is obviousness. As for me, it was
            sometimes slightly difficult to explain to somebody not familiar with
            Python what

            for n in range(1,10,2):
            bla-bla-bla

            stands for. Arithmetic sequence IMHO isn't that kind of thing when you
            need to know some
            special function to use it (is everything OK with my english here?)

            Comment

            • Gregory Petrosyan

              #21
              Re: Arithmetic sequences in Python

              Steven D'Aprano wrote:[color=blue]
              > Python indexing deliberately goes to one-past-the-end counting for a
              > reason: it helps prevent off-by-one signpost errors. This syntax goes
              > against that decision, and adds one more thing to memorise about Python:
              > the end index is not included in the list, except for arithmetic
              > sequences, where it is, sometimes but not necessarily. In [5,6,10] the end
              > index 10 is included; in [5,7,10] it isn't.[/color]

              1) both in [5,6,10] and [5,7,10] 10 is included ;-)
              And as for [5,6 .. 10] and [5,7 .. 10]... First one should look
              like [5 .. 10] I think. But you are right:
              it looks like a problem that in one case 10 is included and in
              other not. I should think about it.

              2) I think there's nothing to memorise: in mathematics [1,2 .. 10]
              includes 10, almost everybody knows
              it.
              The thing that newcomer should memorise is (IMHO) _not_so_obvious _
              behaviour of 'range'. You
              may laugh at me, if you want. But look at Cormen's pseudocode: "for
              j=1 to n" includes 'n'. (And
              indexing starts from 1, not from 0, but that's another story).
              Also, for non-programmer including the
              borders is obvious, not otherwise.

              Comment

              • Paul Rubin

                #22
                Re: Arithmetic sequences in Python

                "Gregory Petrosyan" <gregory.petros yan@gmail.com> writes:[color=blue]
                > 1) both in [5,6,10] and [5,7,10] 10 is included ;-)
                > And as for [5,6 .. 10] and [5,7 .. 10]... First one should look
                > like [5 .. 10] I think. But you are right:
                > it looks like a problem that in one case 10 is included and in
                > other not. I should think about it.[/color]

                [5,7 .. 10] means [5,7,9,11,13,15, ... ] limited to x<=10, so that
                means [5,7,9]. 10 is not included.

                Comment

                • Paul Rubin

                  #23
                  Re: Arithmetic sequences in Python

                  "Gregory Petrosyan" <gregory.petros yan@gmail.com> writes:[color=blue]
                  > 1) [f(n), f(n)-1 .. 0] can be easily catched by interpreter, and f(n)
                  > can be evaluated only once.[/color]

                  I think it would be counterintuitiv e for the interpreter to do that.
                  If I type f(n) twice I expect it to be evaluated twice.
                  [color=blue]
                  > 2) if you need right border excluded, I think [0 .. n) is very clear
                  > (and consistent with mathematics).[/color]

                  Oh man, that's really ugly. I'm not crazy about Ruby's "..." either
                  though I guess it's ok. Using colon for non-inclusion might be more
                  Python-like since it resembles both the syntax and behavior of an
                  existing python range:

                  [0.. : n]

                  (hmm, it does look kind of ugly).
                  [color=blue]
                  > 3) Of course, in some cases 'range' is more readable. As for your
                  > examples:
                  >
                  > [0,..9] versus range(10)
                  > [55, ...73] versus range(55, 74)
                  > [1, 3, ..len(mystr)] versus range(1, len(mystr)+1, 2)
                  > [55, 65, 295] versus range(55, 296, 10)[/color]

                  Those examples should be written:

                  [0 .. 9] versus range(10)
                  [55 .. 73] versus range(55,74)
                  [1, 3, .. len(mystr)] versus range(1, len(mystr)+1, 2)
                  [55, 65, .. 295] versus range(55, 296, 10)

                  I find the ".." version more readable than the "range" version for
                  all four cases. YMMV.
                  [color=blue]
                  > 4) Proposed syntax can be easily extended to support chars (or any
                  > other enumeration). (Maybe, without _implied_ :-) step parameter):
                  >
                  > ['a' .. 'd'] -> ['a','b','c','d'] (let it be a list for consistency)[/color]

                  Hmm:

                  Hugs.Base> ['a'..'d']
                  "abcd"
                  Hugs.Base>

                  Note that "abcd" in Haskell is actually a list of chars.
                  [color=blue]
                  > ('a' ..) -> generator that yields english alphabet[/color]

                  I think this has to be an infinite generator or one that yields all
                  the ascii chars starting with 'a'.

                  Comment

                  • Xavier Morel

                    #24
                    Re: Arithmetic sequences in Python

                    Steven D'Aprano wrote:[color=blue]
                    > On Mon, 16 Jan 2006 12:51:58 +0100, Xavier Morel wrote:
                    >[color=green]
                    >> For those who'd need the (0..n-1) behavior, Ruby features something that
                    >> I find quite elegant (if not perfectly obvious at first), (first..last)
                    >> provides a range from first to last with both boundaries included, but
                    >> (first...last) (notice the 3 periods)[/color]
                    >
                    > No, no I didn't.
                    >
                    > Sheesh, that just *screams* "Off By One Errors!!!". Python deliberately
                    > uses a simple, consistent system of indexing from the start to one past
                    > the end specifically to help prevent signpost errors, and now some folks
                    > want to undermine that.
                    >
                    > *shakes head in amazement*
                    >
                    >[/color]
                    Steven, I never said that Python should use this syntax, I merely showed
                    how it was done in Ruby.

                    It's nothing more than a ... basis of discussion... not a "I want that
                    !!ONE" post (if I did, i'd be using Ruby and posting on c.l.r)

                    (and you didn't what by the way?)

                    Ok scratch that, you didn't notice the 3 periods.

                    Comment

                    • Xavier Morel

                      #25
                      Re: Arithmetic sequences in Python

                      Steven D'Aprano wrote:[color=blue]
                      > On Mon, 16 Jan 2006 12:51:58 +0100, Xavier Morel wrote:
                      >[color=green]
                      >> For those who'd need the (0..n-1) behavior, Ruby features something that
                      >> I find quite elegant (if not perfectly obvious at first), (first..last)
                      >> provides a range from first to last with both boundaries included, but
                      >> (first...last) (notice the 3 periods)[/color]
                      >
                      > No, no I didn't.
                      >
                      > Sheesh, that just *screams* "Off By One Errors!!!". Python deliberately
                      > uses a simple, consistent system of indexing from the start to one past
                      > the end specifically to help prevent signpost errors, and now some folks
                      > want to undermine that.
                      >
                      > *shakes head in amazement*
                      >
                      >[/color]
                      Steven, I never said that Python should use this syntax, I merely showed
                      how it was done in Ruby.

                      It's nothing more than a ... basis of discussion... not a "I want that
                      !!ONE" post (if I did, i'd be using Ruby and posting on c.l.r)

                      (and you didn't what by the way?)

                      Comment

                      • Tom Anderson

                        #26
                        Re: Arithmetic sequences in Python

                        On Mon, 16 Jan 2006, it was written:
                        [color=blue]
                        > There's something to be said for that. Should ['a'..'z'] be a list or a
                        > string?[/color]

                        And while we're there, what should ['aa'..'zyzzoget on'] be?

                        tom

                        --
                        Socialism - straight in the mainline!

                        Comment

                        • Tom Anderson

                          #27
                          Re: Arithmetic sequences in Python

                          On Mon, 16 Jan 2006, Gregory Petrosyan wrote:
                          [color=blue]
                          > Please visit http://www.python.org/peps/pep-0204.html first.
                          >
                          > As you can see, PEP 204 was rejected, mostly because of not-so-obvious
                          > syntax. But IMO the idea behind this pep is very nice.[/color]

                          Agreed. Although i have to say, i like the syntax there - it seems like a
                          really natural extension of existing syntax.
                          [color=blue]
                          > So, maybe there's a reason to adopt slightly modified Haskell's syntax?[/color]

                          Well, i do like the .. - 1..3 seems like a natural way to write a range.
                          I'd find 1...3 more natural, since an ellipsis has three dots, but it is
                          slightly more tedious.

                          The natural way to implement this would be to make .. a normal operator,
                          rather than magic, and add a __range__ special method to handle it. "a ..
                          b" would translate to "a.__range__(b) ". I note that Roman Suzi proposed
                          this back in 2001, after PEP 204 was rejected. It's a pretty obvious
                          implementation, after all.
                          [color=blue]
                          > Something like
                          >
                          > [1,3..10] --> [1,3,5,7,9]
                          > (1,3..10) --> same values as above, but return generator instead of
                          > list
                          > [1..10] --> [1,2,3,4,5,6,7,8 ,9,10]
                          > (1 ..) --> 'infinite' generator that yield 1,2,3 and so on
                          > (-3,-5 ..) --> 'infinite' generator that yield -3,-5,-7 and so on[/color]

                          -1. Personally, i find the approach of specifying the first two elements
                          *absolutely* *revolting*, and it would consistently be more awkward to use
                          than a start/step/stop style syntax. Come on, when do you know the first
                          two terms but not the step size?
                          [color=blue]
                          > 1) "[]" means list, "()" means generator[/color]

                          Yuck. Yes, i know it's consistent with list comps and genexps, but yuck to
                          those too!

                          Instead, i'd like to see lazy lists used here - these look like lists, and
                          can be used exactly like a list, but if all you want to do is iterate over
                          them, they don't need to instantiate themselves in memory, so they're as
                          efficient as an iterator. The best of both worlds! I've written a sketch
                          of a generic lazy list:



                          Note that this is what xrange does already (as i've just discovered).

                          tom

                          --
                          Socialism - straight in the mainline!

                          Comment

                          • Tom Anderson

                            #28
                            Re: Arithmetic sequences in Python

                            On Mon, 16 Jan 2006, Alex Martelli wrote:
                            [color=blue]
                            > Steven D'Aprano <steve@REMOVETH IScyber.com.au> wrote:
                            >[color=green]
                            >> On Mon, 16 Jan 2006 12:51:58 +0100, Xavier Morel wrote:
                            >>[color=darkred]
                            >>> For those who'd need the (0..n-1) behavior, Ruby features something
                            >>> that I find quite elegant (if not perfectly obvious at first),
                            >>> (first..last) provides a range from first to last with both boundaries
                            >>> included, but (first...last) (notice the 3 periods)[/color]
                            >>
                            >> No, no I didn't.
                            >>
                            >> Sheesh, that just *screams* "Off By One Errors!!!". Python deliberately
                            >> uses a simple, consistent system of indexing from the start to one past
                            >> the end specifically to help prevent signpost errors, and now some
                            >> folks want to undermine that.
                            >>
                            >> *shakes head in amazement*[/color]
                            >
                            > Agreed. *IF* we truly needed an occasional "up to X *INCLUDED*"
                            > sequence, it should be in a syntax that can't FAIL to be noticed, such
                            > as range(X, endincluded=Tru e).[/color]

                            How about first,,last? Harder to do by mistake, but pretty horrible in its
                            own way.

                            tom

                            --
                            Socialism - straight in the mainline!

                            Comment

                            • Paul Rubin

                              #29
                              Re: Arithmetic sequences in Python

                              Tom Anderson <twic@urchin.ea rth.li> writes:[color=blue]
                              > The natural way to implement this would be to make .. a normal
                              > operator, rather than magic, and add a __range__ special method to
                              > handle it. "a .. b" would translate to "a.__range__(b) ". I note that
                              > Roman Suzi proposed this back in 2001, after PEP 204 was
                              > rejected. It's a pretty obvious implementation, after all.[/color]

                              Interesting, but what do you do about the "unary postfix" (1 ..)
                              infinite generator?
                              [color=blue][color=green]
                              > > (-3,-5 ..) --> 'infinite' generator that yield -3,-5,-7 and so on[/color]
                              >
                              > -1. Personally, i find the approach of specifying the first two
                              > elements *absolutely* *revolting*, and it would consistently be more
                              > awkward to use than a start/step/stop style syntax. Come on, when do
                              > you know the first two terms but not the step size?[/color]

                              Usually you know both, but showing the first two elements makes
                              sequence more visible. I certainly like (1,3..9) better than (1,9;2)
                              or whatever.
                              [color=blue][color=green]
                              > > 1) "[]" means list, "()" means generator[/color]
                              > Yuck. Yes, i know it's consistent with list comps and genexps, but
                              > yuck to those too![/color]

                              I'd be ok with getting rid of [] and just having generators or
                              xrange-like class instances. If you want to coerce one of those to a
                              list, you'd say list((1..5)) instead of [1..5].

                              Comment

                              • Paul Rubin

                                #30
                                Re: Arithmetic sequences in Python

                                Dennis Lee Bieber <wlfraed@ix.net com.com> writes:[color=blue]
                                > What would be expected from
                                > [1, 3, 6 .. 20]
                                > ???[/color]

                                In Haskell:

                                Hugs.Base> [1,3,6..20]
                                ERROR - Syntax error in expression (unexpected `..')
                                Hugs.Base>
                                [color=blue]
                                > Again, I see [1, 3, 6, 7, 8, 9, 10, ... , 18, 19][/color]

                                You'd write that in Haskell as 1:3:[6..19]. In Python I guess
                                you'd say [1,3]+[6..19].

                                Comment

                                Working...