Solusi sampai saat ini hanya berurusan dengan daftar, dan kebanyakan adalah menyalin daftar tersebut. Dalam pengalaman saya, banyak kali hal itu tidak mungkin.
Juga, mereka tidak berurusan dengan fakta bahwa Anda dapat memiliki elemen berulang dalam daftar.
Judul pertanyaan Anda mengatakan "Nilai sebelumnya dan berikutnya di dalam satu lingkaran ", tetapi jika Anda menjalankan sebagian besar jawaban di sini di dalam loop, Anda akan berulang kali mengulang seluruh daftar di setiap elemen untuk menemukannya.
Jadi saya baru saja membuat fungsi itu. menggunakanitertools modul, membagi dan memotong iterable, dan menghasilkan tupel dengan elemen sebelumnya dan berikutnya bersama-sama. Tidak persis seperti yang dilakukan kode Anda, tetapi patut untuk dilihat, karena mungkin dapat menyelesaikan masalah Anda.
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)
Kemudian gunakan dalam satu lingkaran, dan Anda akan memiliki item sebelumnya dan berikutnya di dalamnya:
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
Hasil:
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
Ini akan bekerja dengan daftar ukuran apa pun (karena tidak menyalin daftar), dan dengan iterable apa pun (file, set, dll). Dengan cara ini Anda bisa mengulang urutan, dan memiliki item sebelumnya dan berikutnya tersedia di dalam loop. Tidak perlu mencari lagi item tersebut secara berurutan.
Penjelasan singkat tentang kode tersebut:
tee digunakan untuk membuat 3 iterator independen secara efisien di atas urutan input
chainmenghubungkan dua urutan menjadi satu; ini digunakan di sini untuk menambahkan urutan elemen tunggal[None] keprevs
islice digunakan untuk membuat urutan semua elemen kecuali yang pertama, lalu chain digunakan untuk menambahkan aNone ke ujungnya
- Sekarang ada 3 urutan independen berdasarkan
some_iterable tampilan tersebut:
prevs: None, A, B, C, D, E
items: A, B, C, D, E
nexts: B, C, D, E, None
- akhirnya
izip digunakan untuk mengubah 3 urutan menjadi satu urutan triplet.
Perhatikan bahwa izipberhenti ketika urutan input apa pun habis, jadi elemen terakhir prevsakan diabaikan, yang benar - tidak ada elemen sehingga elemen terakhir akan menjadi miliknya prev. Kami dapat mencoba untuk melepaskan elemen terakhir dari prevstapiizip perilaku membuatnya menjadi berlebihan
Juga mencatat bahwa tee, izip, islicedanchain berasal dari itertoolsmodul; mereka beroperasi pada urutan masukan mereka secara on-the-fly (malas), yang membuatnya efisien dan tidak memperkenalkan kebutuhan untuk memiliki seluruh urutan dalam memori sekaligus setiap saat.
Dalam python 3, ia akan menampilkan kesalahan saat mengimpor izip, Anda dapat menggunakan zipbukan izip. Tidak perlu impor zip, itu adalah standar di python 3- sumber