Dotychczasowe rozwiązania zajmowały się tylko listami, a większość z nich kopiuje listę. Z mojego doświadczenia wynika, że wiele razy nie jest to możliwe.
Nie zajmują się też tym, że na liście mogą znajdować się powtarzające się elementy.
Tytuł pytania brzmi „ Poprzednie i następne wartości wewnątrz pętli ”, ale jeśli większość odpowiedzi uruchomisz w pętli, w końcu ponownie przejdziesz przez całą listę dla każdego elementu, aby go znaleźć.
Więc właśnie stworzyłem funkcję, która. używając itertoolsmodułu, dzieli i dzieli iterowalne elementy oraz generuje krotki z poprzednimi i następnymi elementami razem. Nie do końca to, co robi twój kod, ale warto przyjrzeć się temu, ponieważ prawdopodobnie może rozwiązać twój problem.
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)
Następnie użyj go w pętli, a będziesz mieć w nim poprzednie i następne elementy:
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
Wyniki:
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
Będzie działać z każdą listą rozmiarów (ponieważ nie kopiuje listy) oraz z dowolnymi iterowalnymi (pliki, zestawy itp.). W ten sposób możesz po prostu iterować po sekwencji i mieć poprzednie i następne elementy dostępne w pętli. Nie ma potrzeby ponownego wyszukiwania pozycji w sekwencji.
Krótkie wyjaśnienie kodu:
tee służy do wydajnego tworzenia 3 niezależnych iteratorów w sekwencji wejściowej
chainłączy dwie sekwencje w jedną; jest tutaj używany do dołączania sekwencji jednoelementowej [None]doprevs
islicesłuży do tworzenia sekwencji wszystkich elementów z wyjątkiem pierwszego, a następnie chainsłuży do dołączania Nonena jego końcu a
- Istnieją teraz 3 niezależne sekwencje,
some_iterablektóre wyglądają następująco:
prevs: None, A, B, C, D, E
items: A, B, C, D, E
nexts: B, C, D, E, None
- ostatecznie
izipsłuży do zamiany 3 sekwencji w jedną sekwencję trojaczków.
Zauważ, że izipzatrzymuje się, gdy jakakolwiek sekwencja wejściowa zostanie wyczerpana, więc ostatni element prevszostanie zignorowany, co jest poprawne - nie ma takiego elementu, który byłby jego ostatnim elementem prev. Moglibyśmy spróbować oderwać ostatnie elementy od, prevsale izipzachowanie sprawia, że jest to zbędne
Należy również pamiętać, że tee, izip, islicei chainpochodzą z itertoolsmodułu; operują na swoich sekwencjach wejściowych w locie (leniwie), co czyni je wydajnymi i nie wprowadza konieczności posiadania w pamięci całej sekwencji na raz.
W python 3programie pokaże błąd podczas importowania izip, możesz użyć zipzamiast izip. Nie ma potrzeby importu zip, predefiniowane jest w python 3- źródło