== The periodic strangeness of idiomatic Python Suppose that you want to do something N times, for whatever reason. In C, the straightforward and idiomatic way to do this is a _for_ loop; '_for (i = 0; i < times; i++) { .... }_'. Since Python doesn't have this form of a _for_ loop, the Python equivalent is a _while_ loop. However, many people would probably say that this isn't idiomatic Python. What I think of as the idiomatic Python way to do 'do something N times' is: > for _ in range(0, times): > .... (Some people will use _xrange()_ instead of _range()_ here.) This is certainly what instantly popped into my head when I ran into this situation recently and at first I didn't think any more of it. But once I began actually looking at this it started getting stranger and stranger, less like a clear language idiom and much more like a convention. Let me run down a number of the ways that this is strange: * It's a rather indirect way of expressing 'do something N times'. The C _for_ loop is pretty direct by contrast. (With that said, I'm not sure a _while_ loop would be that much more direct. The directness advantage that C has is that all parts of the _for_ loop's control are there in one chunk; a _while_ loop spreads them out in three different lines.) * We're doing things in this odd way partly to use as many builtins as possible, often in the name of (nominal) efficiency. Yes, this avoids a couple of extra lines to initialize and increment an otherwise unused counter, but I don't think that really makes it clearer. * In the pursuit of this idiom we're creating a list or at least an iterator and walking it, throwing away the result. In many languages this would be wince-inducingly inefficient (or at least much worse than basic integer arithmetic with a variable). It's a (probable) win in CPython because of the whole builtins vs non-builtins issue. (Not only is _range()_ a builtin, but _for_ with iterators has direct bytecode support.) * You pretty much need to know this idiom in order to understand this code without a bunch of thought (which is not the case for the C version). A special tricky point is the use of `((_))' as a special variable name used to indicate 'I don't care about this variable, I just have to have something here'; this is entirely a convention in (some) Python programming circles, with no special meaning in the language itself. (As a corollary, I doubt that this is an idiom that would naturally occur to people who are not already immersed in Python.) * When using this idiom you'd better remember the exact effects of _range()_/_xrange()_, since eg '_range(1, times)_' is very much not what you want. (Again the C equivalent has this clearly visible.) The overall summary of this is that the Python idiom really is close to being an *idiom*, in the literal definition of the word: it is an expression whose meaning is not clearly and immediately understandable from a quick read of its component parts. By contrast the C idiom is much clearer (at least for me). (I don't think that all of this makes the Python idiom bad; it remains the most compact and probably the most efficient way of expressing this. And even without knowing this idiom off the top of your head I think it's reasonably clear roughly what it does (and it's reasonably easy to work out all of the details).)