Reimplementing enumerate() to produce a sequence or iterator Apparently it is possible to implement enumerate so it produces a sequence when given a sequence, and produces an iterable otherwise. Sequence can be safely reversed. This works by replacing the builtin function. Other similar functions could be made this way, too.

class EnumeratedSequence:
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return (index,self.items[index])

    def __len__(self):
        return len(self.items)

def enumerate(items):
    if hasattr(items, '__getitem__'):
        print 'Sequence detected'
        return EnumeratedSequence(items)
    else:
        print 'Iterator detected'
        return __builtin__.enumerate(items)

print list(reversed(enumerate('abcdef')))
print list(enumerate(reversed('abcdef')))


Which outputs:

Sequence detected
[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]
Iterator detected
[(0, 'f'), (1, 'e'), (2, 'd'), (3, 'c'), (4, 'b'), (5, 'a')]


This was a solution to a problem of reversed(enumerate(...)) failing.
First of, depending on the implementations, __builtin__ may not be directly available (it seems to be in IPyton, but not in CPython). You should import __builtin__ beforehand so __builtin__ will always be in the global namespace. CPython implementation also have __builtins__ (with an s) directly available without imports.

Second, you should remove the print statements in enumerate. I guess it was for demonstrations purposes but if you want to use that in real code it will be pure noise.

Other than that, I’d just add a docstring to enumerate to explain the new behavior.

However, since you are using Python 2, you can take advantage of some features that were removed in Python 3. Namely the difference between zip and itertools.izip. The former returns a list, the latter an iterator: pretty much what you’re after. And since enumerate is somewhat equivalent to zipping itertools.count with its parameters, it is very simple to achieve what you’re looking for:

from itertools import count, izip

def enumerate(iterable):
    zip_ = zip if hasattr(iterable, '__getattr__') else izip
    return zip_(count(), iterable)