On Thu, 21 Jul 2016 03:46 am, Chris Angelico wrote: > On Thu, Jul 21, 2016 at 3:42 AM, Ian Kelly <ian.g.ke...@gmail.com> wrote: >> I had occasion to write something like this: >> >> for i, n in reversed(enumerate(x)): pass >> >> Of course this fails with "TypeError: argument to reversed() must be a >> sequence". I ended up using this instead: >> >> for i, n in zip(reversed(range(len(x))), reversed(x)): pass > > At the cost of coalescing the enumeration, you could: > > for i, n in reversed(list(enumerate(x))): pass > > It's reasonably clean but less efficient.
Less efficient than what? reversed() only operates on sequences, so it can't operate on arbitrary iterators of unknown length? Possibly of indefinite length? def iter(): while random.random() > 0.01: yield random.random() So in the most general case, you have to form a list before you can reverse it. Personally, I think your version is the most straightforward and obvious solution that works on anything. (Well, perhaps not on infinite iterators.) Yes, you have to convert x into a list, but that's in general the only way to use reversed() anyway. If your needs are not too great, or simplicity of code is more important than The "best" solution might be some more work: you might convert x into a list only if it's an iterator, then iterate over it in reverse: def sequencefy(x): if x is iter(x): return list(x) return x def enumerate_down(it): seq = sequencefy(it) n = len(seq) - 1 for item in reversed(seq): yield (n, item) n -= 1 for i, item = enumerate_down(x): ... An advantage of this is that it works well with lazy sequences like (x)range. There's no need to build up a huge list of (index, item) pairs before reversing it. -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list