Как уже упоминали @Cybis и другие, вы не можете сохранить сложность O (N) со списками Python; вам придется создать связанный список. С риском доказать 10-е правило Гринспуна , вот такое решение:
class cons(tuple):
__slots__=()
def __new__(cls, car, cdr):
return tuple.__new__(cls, (car,cdr))
@classmethod
def from_seq(class_, l):
result = None
for el in reversed(l):
result = cons(el, result)
return result
@property
def car(self): return self._getitem(0)
@property
def cdr(self): return self._getitem(1)
def _getitem(self, i):
return tuple.__getitem__(self, i)
def __repr__(self):
return '(%s %r)' % (self.car, self.cdr)
def __iter__(self):
v = self
while v is not None:
yield v.car
v = v.cdr
def __len__(self):
return sum(1 for x in self)
def __getitem__(self, i):
v = self
while i > 0:
v = v.cdr
i -= 1
return v.car
def maplist(func, values):
result = [ ]
while values is not None:
result.append(func(values))
values = values.cdr
return result
Тестирование дает:
>>> l = cons.from_seq([1,2,3,4])
>>> print l
(1 (2 (3 (4 None))))
>>> print list(l)
[1, 2, 3, 4]
>>> print maplistr(lambda l: list(reversed(l)), cons.from_seq([1,2,3]))
[[3, 2, 1], [3, 2], [3]]
РЕДАКТИРОВАТЬ: Вот решение на основе генератора, которое в основном решает ту же проблему без использования связанных списков:
import itertools
def mapiter(func, iter_):
while True:
iter_, iter2 = itertools.tee(iter_)
iter_.next()
yield func(iter2)
Тестирование дает:
>>> print list(mapiter(lambda l: list(reversed(list(l))), [1,2,3]))
[[3, 2, 1], [3, 2], [3]]