5

If I want to iterate n times in Java, I write:

for (i = 0; i < n; i++) {
    // do stuff
}

In Python, it seems the standard way to do this is:

for x in range(n):
    # do stuff

As always, Python is more concise and more readable. But the x bothers me, as it is unnecessary, and PyDev generates a warning, since x is never used.

Is there a way to do this that doesn't generate any warnings, and doesn't introduce unnecessary variables?

Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
  • 1
    Why doesn't the `i` in Java bother you as unnecessary? – S.Lott Aug 19 '10 at 17:01
  • @S.Lott I didn't say that the `i` doesn't bother me. I like the Python syntax better, as usual. But there is the fact that the `i` in Java seems to be used, and I'm not scolded for not using it in the loop. – Eric Wilson Aug 19 '10 at 17:16
  • The `i` may not actually be used. So it's the "scolding"? Is that the issue? – S.Lott Aug 19 '10 at 18:08
  • Steven, I love Python. It's my favorite language, though I don't know it well. I'm not trying to complain or pick a fight. My IDE told me I wasn't doing something in the best way, and so I sought the best way. I'm happy now, but it seems that my question seems strange to you. Fine. Eventually I'll understand Python well enough that the `self` stuff seems normal. But for now, I'll ask questions that seem odd to one as experienced as you. – Eric Wilson Aug 19 '10 at 18:23
  • 2
    Insert obligatory warning about range(). If n is potentially large, use xrange() instead (if your Python implementation supports it) or itertools.islice(). – tc. Aug 19 '10 at 19:26

2 Answers2

6

Idiomatic Python (and many other languages) would have you use _ as the temporary variable, which generally indicates to readers that the variable is intentionally unused.

Aside from that convention, the in loop-construct in Python always requires you to iterate over something and assign that value to a variable.

(The comments in the accepted answer of this question suggest that PyDev won't create a warning for _).

for _ in range(n):
    # do stuff
Jean-Francois T.
  • 11,549
  • 7
  • 68
  • 107
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
2

In Python, you don't create an additional variable in the sort of situation you described.

for i in range(10):

Creates a range object, over which the loop iterates. The range object holds it's current value at any given time. i is merely a name that's created and bound to this value.

The variable exists whether it has a name or not, since the range object must know it's current value.

If you think about a loop in terms of cpu instructions, you see why there must be a variable:

push x
loop:
    do something
    increment x
    jump if x > y
    goto loop

There is a facility in some JIT compiled languages that sometimes detects a loop being just a small amount of repetitions of the same code and optimises the code to be a series of the same instructions. But, as far as I know, python does no such thing.

Here's a for-loop in bytecode:

  4           0 SETUP_LOOP              20 (to 23) 
              3 LOAD_GLOBAL              0 (range) 
              6 LOAD_FAST                0 (x) 
              9 CALL_FUNCTION            1 
             12 GET_ITER             
        >>   13 FOR_ITER                 6 (to 22) 
             16 STORE_FAST               1 (i) 

  5          19 JUMP_ABSOLUTE           13 
        >>   22 POP_BLOCK            

Notice that there's no comparison. The loop is quit by the iteration object raising StopIteration, the interpreter then looks up the loop setup and jumps to the end of the loop (23 in this case).

Of course you could avoid all of this by just repeating your code x number of times. As soon as this number may vary, there needs to be some sort of facility to provide next() and StopIteration for the for loop to work.Remember, python's for-loop is if anything comparable to a for-each loop in Java. There really isn't a traditional for-loop available at all.

Just as an aside: I always use i, j and k for iterating variables. Using the underscore somehow seems inelegant to me.

Stefano Palazzo
  • 4,212
  • 2
  • 29
  • 40