Steven D'Aprano wrote:
For backwards compatibilty reasons, we can't just make map() work like this, because that's a change in behaviour.
Actually, I think it's possible to get the best of both worlds. Consider this: from operator import itemgetter class MapView: def __init__(self, func, *args): self.func = func self.args = args self.iterator = None def __len__(self): return min(map(len, self.args)) def __getitem__(self, i): return self.func(*list(map(itemgetter(i), self.args))) def __iter__(self): return self def __next__(self): if not self.iterator: self.iterator = map(self.func, *self.args) return next(self.iterator) If you give it sequences, it behaves like a sequence: >>> a = [1, 2, 3, 4, 5] >>> b = [2, 3, 5] >>> from math import pow >>> m = MapView(pow, a, b) >>> print(list(m)) [1.0, 8.0, 243.0] >>> print(list(m)) [1.0, 8.0, 243.0] >>> print(len(m)) 3 >>> print(m[1]) 8.0 If you give it iterators, it behaves like an iterator: >>> m = MapView(pow, iter(a), iter(b)) >>> print(next(m)) 1.0 >>> print(list(m)) [8.0, 243.0] >>> print(list(m)) [] >>> print(len(m)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/greg/foo/mapview/mapview.py", line 14, in __len__ return min(map(len, self.args)) TypeError: object of type 'list_iterator' has no len() If you use it as an iterator after giving it sequences, it also behaves like an iterator: >>> m = MapView(pow, a, b) >>> print(next(m)) 1.0 >>> print(next(m)) 8.0 What do people think? Could we drop something like this in as a replacement for map() without disturbing anything too much? -- Greg _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/