Дотепер рішення стосуються лише списків, і більшість копіюють список. З мого досвіду багато разів це неможливо.
Крім того, вони не мають справи з тим, що у вас можуть бути повторювані елементи у списку.
У заголовку вашого запитання написано " Попереднє і наступне значення всередині циклу ", але якщо більшість відповідей тут запущено всередині циклу, ви в кінцевому підсумку повторите весь список по кожному елементу, щоб знайти його.
Тож я щойно створив функцію, яка. використовуючи 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
- джерелі