valerium
@valerium
Изобретая велосипед

Как экономно сымитировать двусвязный список на Python?

Приветствую.

Мне нужно с каждым элементом последовательности выполнить те или иные действия. Действия зависят от значения предыдущего и следующего элементов в последовательности. Как это сделать красиво и по-питонски?

Городить ради этого полновесный связный список (как это рекомендует Google) не очень-то хочется, особенно если речь идёт о последовательности каких-нибудь скромных целых или коротких строк. После нескольких экспериментов соорудил генератор, чем-то похожий на встроенный enumerate(): принимает последовательность и на каждую итерацию возвращает кортеж из предыдущего, текущего и следующего элементов. Соответственно, если предыдущего или следующего нет, то вместо них возвращается None.

def linked(sequence):
    """
    >>> list(linked([1]))
    [(None, 1, None)]
    >>> list(linked([1, 2]))
    [(None, 1, 2), (1, 2, None)]
    >>> list(linked([1, 2, 3]))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    """
    index = 0
    while index < len(sequence):
        yield (sequence[index - 1] if index else None,
               sequence[index],
               sequence[index + 1] if index + 1 < len(sequence) else None)
        index += 1
    raise StopIteration


Но мне это решение не очень нравится, как-то слишком уж низкоуровнево, отдаёт каким-то Си.

Как это сделать лучше? Есть ли готовые решения?
  • Вопрос задан
  • 1681 просмотр
Решения вопроса 2
def previous_and_next(some_iterable):
    prevs, items, nexts = tee(some_iterable, 3)
    prevs = chain([None], prevs)
    nexts = chain(islice(nexts, 1, None), [None])
    return izip(prevs, items, nexts)
Ответ написан
@nirvimel
def prev_cur_next(list_arg):
    extended_list = [None]
    extended_list.extend(list_arg)
    extended_list.append(None)
    return [extended_list[i - 1:i + 2] for i in xrange(1, len(extended_list) - 1)]


UPD: Сравнительный бенчмакр всех предложенных решений - https://ideone.com/bDogvY
К моему удивлению, мое отстает от решений Артём Клименко и angru ,. Признаю их победу.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы