I've been using python as a tool to solve competitive programming problems for a while now and I've noticed a feature, python would benefit from having. Consider "reversed(enumerate(a))". This is a perfectly readable code, except it's wrong in the current version of python. That's because enumerate returns an iterator, but reversed can take only a sequence type.
The feature I am describing (and proposing) solves this. Introducing an adapter type: this is an iterator, but it's items can be accessed out of order. More formally it has to: 1. Have __getitem__ to allow access by index 2. Have __len__ 3. Be immutable (It is a lot like the sequence protocol) An adapter can be converted to an iterator by accessing it from 0 to len(adapter). Which is done by iter(). (or by __iter__, I don't know which implementation would be "right") ``` iter(a) #is equivalent to (a[i] for i in range(len(a))) ``` For example any tuple is a valid adapter and any list can be easily converted to one. Built-in adapter-generators: "map" function should really return an adapter. ``` #possible implementation m=map(lambda x:x+1,[1,2,3,4,5]) #lambda is not called print(m[3])# gives 5 by calling the lambda on list's 3rd element, which is 4 #simplified implementation class map: def __init__(self,f,a): self.f=f self.a=a def __getitem__(self,idx): return self.f(self.a[idx]) def __len__(self): return len(self.a) ``` enumerate should really return an adapter ``` #simplified implementation class enumerate: def __init__(self,a): self.a = a def __getitem__(self,idx): return idx,self.a[idx] def __len__(self): return len(self.a) ``` reversed should really return an adapter ``` #simplified implementation class reversed: def __init__(self,a): self.a = a self.length=len(a) def __getitem__(self,idx): return self.a[self.length-idx-1] def __len__(self): return self.length ``` zip should really return an adapter range should really return an adapter filter should *not* return an adapter All of those functions return an adapter and take in an adapter. But some (excluding "reversed") should be able take an iterator and return an iterator. So the way I imagine a possible release version to work is that "reversed(enumerate(a))" works if a is an adapter and throws an exception if not Perhaps there should be even an adapter comprehension: ``` Add1 = (a+1 for a) #is equivalent to Add1 = lambda s: map((lambda a: a+1),s) transformed = Add1([1,2,3]) print(transformed[1])# should be 3 ``` This adapter feature also allows you to not use a key argument "key=" for certain functions (which could be non-existing). For example bisect.bisect functions before 3.10 didn't have a key= argument. Some third-party libraries could do this with it's functions too. (Subject to change) -- https://mail.python.org/mailman/listinfo/python-list