Re: steve(a)pearwood.info
> It isn't really well-defined, since enumerate can operate on infinite
> iterators, and you cannot reverse an infinite stream.
It is well defined on any iterable that itself is reversible and has
defined length. For standard types that's lists, strings, dictionary
iterators and some of the collections (deque, dictionary-based counter).
Re: storchaka(a)gmail.com
> Could you please provide evidence that this feature would be quite
> useful? How much usecases can you find in the stdlib?
I needed this while solving a CS problem
https://leetcode.com/problems/container-with-most-water/, which, I agree,
does not tell how useful it is in production projects.
Couldn't find any usecase in stdlib. I could find a usecase in scikit-learn:
https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/pipeline.p…
in case file gets changed, here is a copy:
for i in reversed(range(len(estimators))):
name = names[i]
if name in namecount:
names[i] += "-%d" % namecount[name]
namecount[name] -= 1
It can indeed be that one doesn't have to reverse enumeration very
often in practice. It can also be that people just express their ideas
differently knowing it doesn't work in straight-forward way.
Best Regards,
--
Ilya Kamenshchikov
Hi,
I needed reversed(enumerate(x: list)) in my code, and have discovered that
it wound't work. This is disappointing because operation is well defined.
It is also well defined for str type, range, and - in principle, but not
yet in practice - on dictionary iterators - keys(), values(), items() as
dictionaries are ordered now.
It would also be well defined on any user type implementing __iter__,
__len__, __reversed__ - think numpy arrays, some pandas dataframes, tensors.
That's plenty of usecases, therefore I guess it would be quite useful to
avoid hacky / inefficient solutions like described here:
https://code.activestate.com/lists/python-list/706205/.
If deemed useful, I would be interested in implementing this, maybe
together with __reversed__ on dict keys, values, items.
Best Regards,
--
Ilya Kamen
-----------
p.s.
*Sketch* of what I am proposing:
class reversible_enumerate:
def __init__(self, iterable):
self.iterable = iterable
self.ctr = 0
def __iter__(self):
for e in self.iterable:
yield self.ctr, e
self.ctr += 1
def __reversed__(self):
try:
ri = reversed(self.iterable)
except Exception as e:
raise Exception(
"enumerate can only be reversed if iterable to
enumerate can be reversed and has defined length."
) from e
try:
l = len(self.iterable)
except Exception as e:
raise Exception(
"enumerate can only be reversed if iterable to
enumerate can be reversed and has defined length."
) from e
indexes = range(l-1, -1, -1)
for i, e in zip(indexes, ri):
yield i, e
for i, c in reversed(reversible_enumerate("Hello World")):
print(i, c)
for i, c in reversed(reversible_enumerate([11, 22, 33])):
print(i, c)