views:

159

answers:

2

I'm talking about doing something like:

for(i=n; i>=1; --i) {
   //do something with i
}

I can think of some ways to do so in python (creating a list of range(1,n+1) and reverse it, using while and --i, ...) but I wondered if there's a more elegant way to do it. Is there?

EDIT: Some suggested I use xrange() instead of range() since range returns a list while xrange returns an iterator. But in Python 3 (which I happen to use) range() returns an iterator and xrange doesn't exist.

+7  A: 
for x in reversed(whatever):
    do_something()

This works on basically everything that has a defined order, including xrange objects and lists.

Aaron Gallagher
Aware that reversed function is returning a list. So reversed(range(100000)) will return new list with 100000 items.
Odomontois
@Odomontois, no, it doesn't. It returns an iterator.
Aaron Gallagher
@Odomontois: Huh, that's false: `print reversed([1, 2, 3])` returns a `<listreverseiterator object at 0xb77f1bec>`.
nosklo
Yes. Sorry. It returns result of obj.__reversed__ method. So by default generator objects haven't this like many others iterables. And even reversed(reversed([1,2,3])) raises TypeError. So you HAVE to create a list before send some iterable to reversed in many situations like reversed([expr(i) for i in iterable if cond(i)]) - without brackets it falls.
Odomontois
+7  A: 

range() and xrange() take a third parameter that specifies a step. So you can do the following.

range(10, 0, -1)

Which gives

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

But for iteration, you should really be using xrange instead. So,

xrange(10, 0, -1)
Chinmay Kanchi
Since this question is about iteration please use xrange instead of range (doesn't matter much for small ranges but starts mattering for large ones).
mzz
@mzz -- only in Python 2.x
katrielalex
I used `range` simply because the OP did. `xrange` vs `range` only matters for _really_ large ranges, like hundreds of megabytes. Also, in Python 3.x, this distinction is gone.
Chinmay Kanchi
@Chinmay, why not use your answer as a way of showing best practices to the OP? No reason *not* to suggest using `xrange`.
Aaron Gallagher
Fair enough, edited.
Chinmay Kanchi
What is xrange? Is it the same as range but faster? If so then why is it faster?
snakile
`xrange` produces a _generator_ instead of a `list`. What this means is that instead of taking up all the memory at the start, the value required is produced at the time when it's required. For more details, see http://docs.python.org/tutorial/classes.html#generators
Chinmay Kanchi
Turns out xrange doesn't exist in python 3...
snakile
No, it doesn't. Your question didn't specify which version of python you were using, and the default assumption tends to be python 2.x
Chinmay Kanchi