Is using range() in for loops really Pythonic?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Grant Edwards

    #31
    Re: Is using range() in for loops really Pythonic?

    On 2008-05-12, Ben Finney <bignose+hate s-spam@benfinney. id.auwrote:
    Paddy <paddy3118@goog lemail.comwrite s:
    >
    >I've used Fortran and C and so would tend to use either i,j,k as the
    >unused loop variable above, or, for clarity, call it something
    >descriptive like loop_count, if the loop body would be clearer.
    >
    The problem with all of these names is that they also have long
    precedent as names of values that *will* be used inside the loop.
    I guess people who standardize on loop_count never nest loops. :)
    Because of the precedent of those names, choosing one of those
    names doesn't make it clear to the reader that the value is
    never used; they have no indication from you of that until
    they look over the code a few times. It's implicit rather than
    explicit.
    And when somebody adds a nested loop things fall apart.

    --
    Grant Edwards grante Yow! BARBARA STANWYCK makes
    at me nervous!!
    visi.com

    Comment

    • Paddy

      #32
      Re: Is using range() in for loops really Pythonic?

      On May 12, 3:46 pm, Grant Edwards <gra...@visi.co mwrote:
      On 2008-05-12, Ben Finney <bignose+hate s-s...@benfinney. id.auwrote:
      >
      Paddy <paddy3...@goog lemail.comwrite s:
      >
      I've used Fortran and C and so would tend to use either i,j,k as the
      unused loop variable above, or, for clarity, call it something
      descriptive like loop_count, if the loop body would be clearer.
      >
      The problem with all of these names is that they also have long
      precedent as names of values that *will* be used inside the loop.
      >
      I guess people who standardize on loop_count never nest loops. :)
      >
      Because of the precedent of those names, choosing one of those
      names doesn't make it clear to the reader that the value is
      never used; they have no indication from you of that until
      they look over the code a few times. It's implicit rather than
      explicit.
      >
      And when somebody adds a nested loop things fall apart.
      I don't have an example to hand. A lot of casses of repeat_X_times
      inside a loop of repeat_Y_times would naturally be written as
      repeat_Y*X_time s.
      Oh, wait a bit,
      <oversimplified _example_alert>
      for i in range(3):
      print "Stay!"
      for j in range(2):
      print "Come over."
      </oversimplified_ example_alert>

      Which could become:

      for outer_stay_repe tions in range(3):
      print "Stay!"
      for inner_come_over _repetions in range(2):
      print "Come over."

      But the second is daft. Nested repeats don't neccessarily pose a
      problem to choosing meaningful names for repeat counters that are not
      going to be referenced in the loop body, and most times i,j,k are fine
      for used and un-used loop indices I find.

      - Paddy
      (Or were you just having a laugh ;-)

      Comment

      • Carl Banks

        #33
        Re: Is using range() in for loops really Pythonic?

        On May 12, 3:42 am, Ben Finney <bignose+hate s-s...@benfinney. id.au>
        wrote:
        Because of the precedent of those names, choosing one of those names
        doesn't make it clear to the reader that the value is never used;

        Why is it even necessary to document this? This is the thing that
        baffles me the most about this thread.

        Think about all the various aspect of a varibale:

        * is it some common usage archetype
        * value it represents
        * scope
        * (expected) type
        * physical units of measure
        * software package it belongs to
        * whether it's used in the program or not
        * scalar, structure, or array
        * mutable or constant
        * and so on

        You cannot possibly document all of this pertinent information in the
        name alone. A variable's name is a very limited resource: one can
        only document a tiny number of things, so one must prioritize.

        IMHO, whether a varibale is used or not has got to be one of the least
        important things of all (in no small part because it's easily
        discernable from nearby code). In fact, I'd say it's so irrelevant I
        probably wouldn't have listed it if it wasn't the topic of discussion.

        The first two items I listed are the most important to me. If a
        variable fills the archetypal role of counter, then it ought to be
        named like a counter; this usually trumps all other concerns. (Never
        mind that the varibale here isn't really a counter, it still fills the
        archetypal role of one, which is more important. The name of a
        variable is for the reader's benefit.) So I would have to agree with
        Ivan Illarionov.

        Having said that, if you do think it's most important to document
        whether something is used, I would suggest not using "_" (because it's
        conflicts with gettext conventions) or "dummy" (because it's
        misleading) for it.


        Carl Banks

        Comment

        • Ben Finney

          #34
          Re: Is using range() in for loops really Pythonic?

          Carl Banks <pavlovevidence @gmail.comwrite s:
          IMHO, whether a varibale is used or not has got to be one of the least
          important things of all (in no small part because it's easily
          discernable from nearby code).
          I couldn't disagree more.

          If you're binding a name to a value that will never be used, you're
          doing me (the reader of the code) a great favour if you indicate
          clearly and concisely that this value is not intended to be referenced
          anywhere else. Saving time for the reader is a very important job of
          the writer of code.
          Having said that, if you do think it's most important to document
          whether something is used, I would suggest not using "_" (because
          it's conflicts with gettext conventions) or "dummy" (because it's
          misleading) for it.
          Agreed.

          Note, too, that the ideal answer to this is "don't bind names at all
          to values that will never be used". It's only because the specifics of
          Python's 'for' statement require us to do this that we are discussing
          the ramifications of what to do when what Python requires of us is
          actually unnecessary for our purposes.

          --
          \ "Friendship is born at that moment when one person says to |
          `\ another, 'What! You too? I thought I was the only one!'" -- |
          _o__) C.S. Lewis |
          Ben Finney

          Comment

          • Carl Banks

            #35
            Re: Is using range() in for loops really Pythonic?

            On May 12, 7:03 pm, Ben Finney <bignose+hate s-s...@benfinney. id.au>
            wrote:
            Carl Banks <pavlovevide... @gmail.comwrite s:
            IMHO, whether a varibale is used or not has got to be one of the least
            important things of all (in no small part because it's easily
            discernable from nearby code).
            >
            I couldn't disagree more.
            >
            If you're binding a name to a value that will never be used, you're
            doing me (the reader of the code) a great favour if you indicate
            clearly and concisely that this value is not intended to be referenced
            anywhere else. Saving time for the reader is a very important job of
            the writer of code.
            I don't think knowing in advance whether a variable is going to be
            used or not benefits readability.


            Carl Banks

            Comment

            • Terry Reedy

              #36
              Re: Is using range() in for loops really Pythonic?


              "Ben Finney" <bignose+hate s-spam@benfinney. id.auwrote in message
              news:877ie06kdl .fsf@benfinney. id.au...
              | So, when not using the values that come from the controlling iterator,
              | it's good to make that explicit. If Python supported it, we might
              | prefer to use no name at all for something that isn't used, but the
              | 'for' syntax doesn't allow that.

              But I presume it could if [target 'in'] were optional.

              for range(n): <stuff to do n times>

              It is possible this has been proposed and rejected,
              but I have no specific memory.

              tjr



              Comment

              • Dave Parker

                #37
                Re: Is using range() in for loops really Pythonic?

                On May 10, 8:19 pm, John Salerno <johnj...@NOSPA Mgmail.comwrote :
                It seems somewhat
                artificial to use the for loop to do something a certain number of
                times, like above.
                I agree; it's a common flaw with lots of languages, not just Python.

                I'd be inclined to use something like:

                FOR 8 TIMES DO <statement>.

                or:

                REPEAT <statementFOR 8 TIMES.

                as a compromise between readability and machine-parsability.

                If anyone has other suggestions, please post them here and I'll
                implement one of them next weekend in Flaming Thunder.

                Comment

                • George Sakkis

                  #38
                  Re: Is using range() in for loops really Pythonic?

                  On May 12, 7:03 pm, Ben Finney <bignose+hate s-s...@benfinney. id.au>
                  wrote:
                  Carl Banks <pavlovevide... @gmail.comwrite s:
                  IMHO, whether a varibale is used or not has got to be one of the least
                  important things of all (in no small part because it's easily
                  discernable from nearby code).
                  >
                  I couldn't disagree more.
                  >
                  If you're binding a name to a value that will never be used, you're
                  doing me (the reader of the code) a great favour if you indicate
                  clearly and concisely that this value is not intended to be referenced
                  anywhere else. Saving time for the reader is a very important job of
                  the writer of code.
                  If you push this logic too far, you should del every name immediately
                  after the last statement it is used in the scope. I would generally
                  find less readable some code spread with del every few lines, micro-
                  managing the effective scope of each name. YMMV.

                  George

                  Comment

                  • John Salerno

                    #39
                    Re: Is using range() in for loops really Pythonic?

                    Ben Finney wrote:
                    I think that the idiom
                    >
                    for unused in xrange(10):
                    # do stuff with no reference to 'unused'
                    >
                    is quite common. Is that what you're asking about?
                    Yes. I was more or less asking about the specific situation of using a
                    for loop to do something X number of times, but I think the more
                    generalized problem that everyone is talking about -- using a counter
                    variable that is never referenced in the loop -- probably puts the point
                    I was trying to make in a better light.

                    The reason I even brought this up is because I remember someone saying a
                    while back (probably here on the newsgroup) that the true use of a for
                    loop was to iterate through a sequence (for the purpose of using that
                    sequence), not to do something X number of times. Once they made this
                    comment, I suddenly saw the for loop in a new (and I believe purer)
                    light. That was the first time I realized what it was really meant
                    to do.

                    Using something like:

                    for unused in xrange(10):
                    # do stuff 10 times

                    suddenly seemed to me like a hackish way to replace

                    for (int i=0; i<10; i++) {
                    // do stuff 10 times;
                    }

                    Not that I think the above code (C#) looks all that elegant either. But
                    in C# there is a distinction between the above, and this:

                    foreach (int i in sequence)
                    // do something;

                    which is more closely related to the Python for loop.

                    Now, you could easily make the argument that the Python for loop is a
                    much simpler tool to accomplish *both* of the above, and I suppose that
                    makes sense. Seems a little silly to have two separate for loops to do
                    these things. I just wasn't sure if the "counter" version of the Python
                    for loop was considered slightly unpythonic.

                    Comment

                    • Terry Reedy

                      #40
                      Re: Is using range() in for loops really Pythonic?


                      "John Salerno" <johnjsal@NOSPA Mgmail.comwrote in message
                      news:482912b7$0 $11641$607ed4bc @cv.net...
                      | The reason I even brought this up is because I remember someone saying a
                      | while back (probably here on the newsgroup) that the true use of a for
                      | loop was to iterate through a sequence (for the purpose of using that
                      | sequence), not to do something X number of times.

                      I believe the specific context was to counteract some people's tendency to
                      write
                      for i in range(len(seq)) : do stuff with seq[i]
                      when they would better (more Pythonically) write
                      for item in seq: do stuff with item
                      or even
                      for i,item in enumerate(seq): do stuff with i and item.

                      One subtle but real advantage is that the latter two forms work with
                      iterables that do not have a known-ahead length or which even continue
                      indefinitely.

                      | Once they made this
                      | comment, I suddenly saw the for loop in a new (and I believe purer)
                      | light. That was the first time I realized what it was really meant
                      | to do.

                      That is an important insight. But to me it does not negate the "do
                      something n times" usage when there is no iterable other than range to
                      iterate. Do note that range has *not* been removed from 3.0 and that its
                      main intended usage is for looping.

                      | Now, you could easily make the argument that the Python for loop is a
                      | much simpler tool to accomplish *both* of the above, and I suppose that
                      | makes sense.

                      Yes. Python leans toward minimalism. Proposals for various
                      special-purpose loopin constructs have been rejected. For-loops cover most
                      looping needs; while-loops cover everything else.

                      Terry Jan Reedy



                      Comment

                      • Marc 'BlackJack' Rintsch

                        #41
                        Re: Is using range() in for loops really Pythonic?

                        On Mon, 12 May 2008 11:23:07 -0700, Carl Banks wrote:
                        On May 12, 3:42 am, Ben Finney <bignose+hate s-s...@benfinney. id.au>
                        wrote:
                        >Because of the precedent of those names, choosing one of those names
                        >doesn't make it clear to the reader that the value is never used;
                        >
                        >
                        Why is it even necessary to document this? This is the thing that
                        baffles me the most about this thread.
                        I do it (with a "special" name) because static source checkers issue a
                        warning for unused variables.

                        Ciao,
                        Marc 'BlackJack' Rintsch

                        Comment

                        • Dave Parker

                          #42
                          Re: Is using range() in for loops really Pythonic?

                          REXX's loop construct subsumes all the common uses... And worse, it
                          appears that a repetition and a condition can be part of the single
                          statement.
                          Thank you for pointing out the REXX examples. I am a Kedit user, but
                          had forgotten about the REXX do-loops. I'll keep them in mind when I
                          add an easy way to "do this n times" to Flaming Thunder this weekend.

                          On May 11, 8:53 pm, Dennis Lee Bieber <wlfr...@ix.net com.comwrote:
                          On Mon, 12 May 2008 00:43:08 GMT, Jonathsn Cronin <j...@theworld. com>
                          declaimed the following in comp.lang.pytho n:
                          >
                          I agree in principle; the first is iteration and the second is repetition.
                          In Python, the common idiom for a fixed number of repetitions is iterating
                          over a number range.  This is true in most languages I am familiar with,
                          probably because fixed repetition, where you don't care about the "index"
                          value, is rarely used.
                          >
                          The only language I've used that does have fixed repetition is an (old)
                          dialect of lisp, and I'm not sure it even made it into Common Lisp.  
                          Smalltalk and Ruby do have fixed repetition.
                          >
                                  REXX's loop construct subsumes all the common uses... And worse, it
                          appears that a repetition and a condition can be part of the single
                          statement.
                          >
                          DO FOREVER
                          ...
                          END
                          >
                          DO repeatcount
                          ...
                          END
                          >
                          DO loopvar=first TO last BY step FOR reptcount
                          ...
                          END
                          >
                          (where "TO last", "BY step", "FOR reptcount" are all optional clauses!)
                          >
                          DO WHILE conditional
                          ...
                          END
                          >
                          DO UNTIL conditional
                          ...
                          END
                          >
                                  Mixing modes
                          >
                          DO loopvar=first BY step UNTIL conditional
                          ...
                          END
                          >
                          Hmmm, looks like it's been extended for container objects (those that
                          support MAKEARRAY):
                          >
                          DO item OVER container
                          ...
                          END
                          --
                                  Wulfraed        Dennis Lee Bieber               KD6MOG
                                  wlfr...@ix.netc om.com              wulfr...@bestia ria.com
                                          HTTP://wlfraed.home.netcom.com/
                                  (Bestiaria Support Staff:               web-a...@bestiaria. com)
                                          HTTP://www.bestiaria.com/

                          Comment

                          • Larry Bates

                            #43
                            Re: Is using range() in for loops really Pythonic?

                            John Salerno wrote:
                            I know it's popular and very handy, but I'm curious if there are purists
                            out there who think that using something like:
                            >
                            for x in range(10):
                            #do something 10 times
                            >
                            is unPythonic. The reason I ask is because the structure of the for loop
                            seems to be for iterating through a sequence. It seems somewhat
                            artificial to use the for loop to do something a certain number of
                            times, like above.
                            >
                            Anyone out there refuse to use it this way, or is it just impossible to
                            avoid?
                            I use it quite often, especially if I want to implement a fixed number of
                            retries on a communications channel.

                            -Larry

                            Comment

                            • Lie

                              #44
                              Re: Is using range() in for loops really Pythonic?

                              On May 13, 11:01 am, John Salerno <johnj...@NOSPA Mgmail.comwrote :
                              Ben Finney wrote:
                              I think that the idiom
                              >
                                  for unused in xrange(10):
                                      # do stuff with no reference to 'unused'
                              >
                              is quite common. Is that what you're asking about?
                              >
                              Yes. I was more or less asking about the specific situation of using a
                              for loop to do something X number of times, but I think the more
                              generalized problem that everyone is talking about -- using a counter
                              variable that is never referenced in the loop -- probably puts the point
                              I was trying to make in a better light.
                              >
                              The reason I even brought this up is because I remember someone saying a
                              while back (probably here on the newsgroup) that the true use of a for
                              loop was to iterate through a sequence (for the purpose of using that
                              sequence), not to do something X number of times. Once they made this
                              comment, I suddenly saw the for loop in a new (and I believe purer)
                              light. That was the first time I realized what it was really meant
                              to do.
                              >
                              Using something like:
                              >
                              for unused in xrange(10):
                                  # do stuff 10 times
                              >
                              suddenly seemed to me like a hackish way to replace
                              >
                              for (int i=0; i<10; i++) {
                                  // do stuff 10 times;
                              >
                              }
                              >
                              Not that I think the above code (C#) looks all that elegant either. But
                              in C# there is a distinction between the above, and this:
                              >
                              foreach (int i in sequence)
                                  // do something;
                              >
                              which is more closely related to the Python for loop.
                              >
                              Now, you could easily make the argument that the Python for loop is a
                              much simpler tool to accomplish *both* of the above, and I suppose that
                              makes sense. Seems a little silly to have two separate for loops to do
                              these things. I just wasn't sure if the "counter" version of the Python
                              for loop was considered slightly unpythonic.
                              What was unPythonic, I think, as most people would agree, is to use
                              for like this:

                              --
                              for i in xrange(len(lst) ):
                              pass
                              --

                              In VB, my language before Python, I've never used For Each even for a
                              sequence (Array, in VB), it seems too messy back then. Now, with
                              Python that only allowed a foreach statement, I realized that I never
                              really needed a for i in range(10) at all. Most of the time the places
                              where I need to do that is where the code is just a test code that
                              loops a certain number of times (with randomized input data), almost
                              never (probably never) met that in a real program code. And even in
                              some of those cases, the variables are usually used too (as a test
                              argument to the function being tested) or for logging purpose.

                              On May 13, 8:25 pm, Larry Bates <larry.ba...@we bsafe.com`wrote :
                              (snip)
                              I use it quite often, especially if I want to implement a fixed number of
                              retries on a communications channel.
                              >
                              -Larry
                              That still have semantic meaning: 'tries'. If it was me, I'll go to
                              the trouble of giving names, since I would use it for logging or
                              informational purpose ('first try' 'second try' 'third try' 'no more
                              try').

                              I've never really met a real "do something n times" case, where the
                              variable doesn't hold any semantic meaning that I don't want to use
                              and is not a test case.

                              For me, a _ (or any other dummy variable[1]) is good enough and it's
                              easy to change if later I realized that I actually need to use the
                              variable. I agree though, that i, j, k for unused name is a bad choice
                              because single letter names is in common usage in mathematics.

                              [1] PEP 8 is useless if a certain code base has other agreed
                              convention, as long as the name used for a unused name in certain code
                              base is consistent (and probably documented), it never becomes a
                              problem.

                              Comment

                              • Lie

                                #45
                                Re: Is using range() in for loops really Pythonic?

                                On May 13, 9:20 pm, Lie <Lie.1...@gmail .comwrote:
                                On May 13, 11:01 am, John Salerno <johnj...@NOSPA Mgmail.comwrote :
                                >
                                >
                                >
                                Ben Finney wrote:
                                I think that the idiom
                                >
                                    for unused in xrange(10):
                                        # do stuff with no reference to 'unused'
                                >
                                is quite common. Is that what you're asking about?
                                >
                                Yes. I was more or less asking about the specific situation of using a
                                for loop to do something X number of times, but I think the more
                                generalized problem that everyone is talking about -- using a counter
                                variable that is never referenced in the loop -- probably puts the point
                                I was trying to make in a better light.
                                >
                                The reason I even brought this up is because I remember someone saying a
                                while back (probably here on the newsgroup) that the true use of a for
                                loop was to iterate through a sequence (for the purpose of using that
                                sequence), not to do something X number of times. Once they made this
                                comment, I suddenly saw the for loop in a new (and I believe purer)
                                light. That was the first time I realized what it was really meant
                                to do.
                                >
                                Using something like:
                                >
                                for unused in xrange(10):
                                    # do stuff 10 times
                                >
                                suddenly seemed to me like a hackish way to replace
                                >
                                for (int i=0; i<10; i++) {
                                    // do stuff 10 times;
                                >
                                }
                                >
                                Not that I think the above code (C#) looks all that elegant either. But
                                in C# there is a distinction between the above, and this:
                                >
                                foreach (int i in sequence)
                                    // do something;
                                >
                                which is more closely related to the Python for loop.
                                >
                                Now, you could easily make the argument that the Python for loop is a
                                much simpler tool to accomplish *both* of the above, and I suppose that
                                makes sense. Seems a little silly to have two separate for loops to do
                                these things. I just wasn't sure if the "counter" version of the Python
                                for loop was considered slightly unpythonic.
                                >
                                What was unPythonic, I think, as most people would agree, is to use
                                for like this:
                                >
                                 --
                                    for i in xrange(len(lst) ):
                                        pass
                                 --
                                >
                                In VB, my language before Python, I've never used For Each even for a
                                sequence (Array, in VB), it seems too messy back then. Now, with
                                Python that only allowed a foreach statement, I realized that I never
                                really needed a for i in range(10) at all. Most of the time the places
                                where I need to do that is where the code is just a test code that
                                loops a certain number of times (with randomized input data), almost
                                never (probably never) met that in a real program code. And even in
                                some of those cases, the variables are usually used too (as a test
                                argument to the function being tested) or for logging purpose.
                                >
                                On May 13, 8:25 pm, Larry Bates <larry.ba...@we bsafe.com`wrote :
                                (snip)
                                >
                                I use it quite often, especially if I want to implement a fixed number of
                                retries on a communications channel.
                                >
                                -Larry
                                >
                                That still have semantic meaning: 'tries'. If it was me, I'll go to
                                the trouble of giving names, since I would use it for logging or
                                informational purpose ('first try' 'second try' 'third try' 'no more
                                try').
                                >
                                I've never really met a real "do something n times" case, where the
                                variable doesn't hold any semantic meaning that I don't want to use
                                and is not a test case.
                                >
                                For me, a _ (or any other dummy variable[1]) is good enough and it's
                                easy to change if later I realized that I actually need to use the
                                variable. I agree though, that i, j, k for unused name is a bad choice
                                because single letter names is in common usage in mathematics.
                                >
                                [1] PEP 8 is useless if a certain code base has other agreed
                                convention, as long as the name used for a unused name in certain code
                                base is consistent (and probably documented), it never becomes a
                                problem.
                                On my last message, I'm tempted not to say: "We need to have /dev/null
                                for Python" though I proved to fail.

                                Comment

                                Working...