Раньше я пытался ответить на вопрос, где я хотел бы как можно более итеративно перебирать фрагмент списка.
for x in lst[idx1:]:
не идеален, так как он создает копию (в общем, это O(n)
). Моя следующая мысль заключалась в том, чтобы использовать itertools.islice
. Но если вы посмотрите на документацию, кажется, что islice
вызовет next
, пока не найдет индекс, который он ищет, и в этот момент он начнет давать значения. Это также O(n)
. Похоже, что существует оптимизация, доступная здесь, если объект, переданный в islice
, является list
или tuple
. Кажется, что вы могли выполнять итерацию по "срезу" напрямую (на C) без фактического создания копия. Мне было любопытно, если эта оптимизация находится в источнике, но я ничего не нашел. Я не очень хорошо знаком с C и деревом исходников python, поэтому вполне возможно, что я его пропустил.
Мой вопрос:
Есть ли способ итерации над списком "срез" без создания копии среза списка и без записи через кучу нежелательных элементов (в оптимизированной реализации C)?
Мне хорошо известно, что я могу написать свой собственный генератор для этого (очень наивно, не учитывая тот факт, что многие аргументы должны быть необязательными и т.д.):
def myslice(obj,start,stop,stride):
for i in xrange(start,stop,stride):
yield obj[i]
но это определенно не собирается превзойти оптимизированную реализацию C.
Если вам интересно, зачем мне это нужно, просто перейдя по фрагменту напрямую, рассмотрите разницу между:
takewhile(lambda x: x == 5, lst[idx:]) #copy the tail of the list unnecessarily
и
takewhile(lambda x: x == 5, islice(lst,idx,None)) #inspects the head of the list unnecessarily
и, наконец:
takewhile(lambda x: x == 5, magic_slice(lst,idx,None)) #How to create magic_slice???