Дотепер рішення стосуються лише списків, і більшість копіюють список. З мого досвіду багато разів це неможливо.
Крім того, вони не мають справи з тим, що у вас можуть бути повторювані елементи у списку.
У заголовку вашого запитання написано " Попереднє і наступне значення всередині циклу ", але якщо більшість відповідей тут запущено всередині циклу, ви в кінцевому підсумку повторите весь список по кожному елементу, щоб знайти його.
Тож я щойно створив функцію, яка. використовуючи itertoolsмодуль, розбиває та нарізає ітерабель і генерує кортежі з попереднім та наступним елементами разом. Не зовсім те, що робить ваш код, але варто поглянути, адже це, ймовірно, може вирішити вашу проблему.
from itertools import tee, islice, chain, izip
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)
Потім використовуйте його в циклі, і в ньому будуть попередні та наступні елементи:
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
Результати:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
Він буде працювати з будь-яким списком розмірів (оскільки він не копіює список) та будь-яким ітерабельним (файли, набори тощо). Таким чином, ви можете просто переглядати послідовність і мати попередні та наступні елементи, доступні всередині циклу. Не потрібно повторно шукати елемент у послідовності.
Коротке пояснення коду:
tee використовується для ефективного створення 3 незалежних ітераторів над вхідною послідовністю
chainпов'язує дві послідовності в одну; він використовується тут для додавання одноелементної послідовності [None]доprevs
isliceвикористовується для створення послідовності всіх елементів, крім першого, потім chainвикористовується для додавання а Noneдо його кінця
- Зараз існує 3 незалежних послідовності, заснованих на
some_iterableтому, що виглядають так:
prevs: None, A, B, C, D, E
items: A, B, C, D, E
nexts: B, C, D, E, None
- нарешті
izipвикористовується для зміни 3 послідовностей в одну послідовність триплетів.
Зверніть увагу, що izipзупиняється, коли будь-яка вхідна послідовність вичерпується, тому останній елемент prevsбуде ігноруватися, що правильно - немає такого елемента, яким би був останній елемент prev. Ми могли б спробувати позбутися останніх елементів з, prevsалеizip поведінки, поведінка робить це зайвим
Також відзначимо , що tee, izip, isliceі chainвиходити від itertoolsмодуля; вони оперують своїми вхідними послідовностями на льоту (ліниво), що робить їх ефективними і не створює необхідності мати в пам'яті всю послідовність одночасно в будь-який час.
У python 3, він покаже помилку під час імпорту izip, ви можете використовувати zipзамість izip. Не потрібно імпортувати zip, це заздалегідь визначено в python 3- джерелі