Saya ingin tahu cara terbaik (cara yang lebih ringkas dan "pythonic") untuk melakukan perawatan khusus untuk elemen terakhir dalam for for. Ada sepotong kode yang harus dipanggil hanya antara elemen, ditekan di yang terakhir.
Inilah cara saya saat ini melakukannya:
for i, data in enumerate(data_list):
code_that_is_done_for_every_element
if i != len(data_list) - 1:
code_that_is_done_between_elements
Apakah ada cara yang lebih baik?
Catatan: Saya tidak ingin membuatnya dengan peretasan seperti menggunakan reduce
.;)
Jawaban:
Sebagian besar waktu lebih mudah (dan lebih murah) untuk membuat iterasi pertama sebagai kasus khusus daripada yang terakhir:
Ini akan bekerja untuk semua yang dapat diubah, bahkan bagi mereka yang tidak memiliki
len()
:Terlepas dari itu, saya tidak berpikir ada solusi yang umumnya unggul karena tergantung pada apa yang Anda coba lakukan. Misalnya, jika Anda membuat string dari daftar, secara alami lebih baik menggunakan
str.join()
daripada menggunakanfor
loop "dengan case khusus".Menggunakan prinsip yang sama tetapi lebih kompak:
Terlihat akrab, bukan? :)
Untuk @ofko, dan orang lain yang benar-benar perlu mencari tahu apakah nilai saat ini dari iterable without
len()
adalah yang terakhir, Anda perlu melihat ke depan:Maka Anda dapat menggunakannya seperti ini:
sumber
if
yang bisa dihindari jika loop itu dibagi menjadi dua loop. Namun, ini hanya relevan ketika mengulang daftar data yang sangat besar.next()
. Lalu saya mengeksploitasi iterator itu iterable dengan sendirinya, jadi saya bisa menggunakannya dalamfor
loop sampai habis, iterasi dari yang kedua ke nilai terakhir. Selama ini saya menyimpan nilai saat ini saya mengambil dari iterator secara lokal danyield
yang terakhir sebagai gantinya. Dengan cara ini saya tahu ada satu nilai lagi yang akan datang. Setelah for for loop, saya telah melaporkan setiap nilai selain yang terakhir.Meskipun pertanyaan itu sudah cukup lama, saya datang ke sini melalui google dan saya menemukan cara yang cukup sederhana: Daftar mengiris. Katakanlah Anda ingin meletakkan '&' di antara semua entri daftar.
Ini mengembalikan '1 & 2 & 3'.
sumber
len(l)=1000000
dalam contoh ini, program akan berjalan untuk sementara waktu.append
dianjurkan afaik.l=[1,2,3]; l.append(4);
'Kode antar' adalah contoh pola Kepala-Ekor .
Anda memiliki item, yang diikuti oleh urutan pasangan (antara, item). Anda juga dapat melihat ini sebagai urutan (item, di antara) pasangan yang diikuti oleh item. Secara umum lebih mudah untuk mengambil elemen pertama sebagai spesial dan yang lainnya sebagai case "standar".
Selanjutnya, untuk menghindari kode berulang, Anda harus menyediakan fungsi atau objek lain untuk mengandung kode yang tidak ingin Anda ulangi. Menanamkan pernyataan if dalam satu lingkaran yang selalu salah kecuali satu kali agak konyol.
Ini lebih dapat diandalkan karena sedikit lebih mudah untuk dibuktikan, itu tidak membuat struktur data tambahan (yaitu, salinan daftar) dan tidak memerlukan banyak pemborosan pelaksanaan kondisi jika yang selalu salah kecuali sekali.
sumber
if
pernyataan sehingga argumen "eksekusi sia-sia" tidak berlaku.if
s". Jelas Anda hanya merujuk pada "kebersihan kode"?if
pernyataan benar-benar dianggap bersih oleh komunitas Python?Jika Anda hanya ingin memodifikasi elemen terakhir
data_list
maka Anda dapat menggunakan notasi:Namun, sepertinya Anda melakukan lebih dari itu. Tidak ada yang salah dengan caramu. Saya bahkan melihat sekilas beberapa kode Django untuk tag templat mereka dan mereka pada dasarnya melakukan apa yang Anda lakukan.
sumber
if data != datalist[-1]:
dan menjaga yang lainnya tetap sama akan menjadi cara terbaik untuk mengkode ini menurut saya.jika barangnya unik:
pilihan lain:
sumber
Ini mirip dengan pendekatan Ants Aasma tetapi tanpa menggunakan modul itertools. Ini juga merupakan iterator lagging yang memandang ke depan elemen tunggal dalam aliran iterator:
sumber
Anda dapat menggunakan jendela geser di atas data input untuk mengintip nilai berikutnya dan menggunakan sentinel untuk mendeteksi nilai terakhir. Ini berfungsi pada semua iterable, jadi Anda tidak perlu tahu panjang sebelumnya. Implementasi berpasangan adalah dari resep itertools .
sumber
Apakah tidak ada kemungkinan untuk beralih pada semua-kecuali elemen terakhir, dan memperlakukan yang terakhir di luar loop? Lagi pula, sebuah loop dibuat untuk melakukan sesuatu yang mirip dengan semua elemen yang Anda loop; jika satu elemen membutuhkan sesuatu yang istimewa, itu seharusnya tidak ada di loop.
(lihat juga pertanyaan ini: apakah-elemen-terakhir-dalam-loop-berhak-perlakuan-terpisah )
EDIT: karena pertanyaannya lebih tentang "di antara", baik elemen pertama adalah yang istimewa karena tidak memiliki pendahulunya, atau elemen terakhir adalah khusus karena tidak memiliki penggantinya.
sumber
Saya suka pendekatan @ ethan-t, tetapi
while True
berbahaya dari sudut pandang saya.Di sini,
data_list
adalah agar elemen terakhir sama dengan nilai dengan yang pertama dari daftar. L dapat ditukar dengandata_list
tetapi dalam kasus ini hasilnya kosong setelah loop.while True
juga dimungkinkan untuk digunakan jika Anda memeriksa daftar itu tidak kosong sebelum pemrosesan atau pemeriksaan tidak diperlukan (aduh!).Bagian yang baik adalah cepat. Yang buruk - itu bisa dirusak (
data_list
menjadi kosong).Solusi paling intuitif:
Oh ya, Anda sudah mengusulkannya!
sumber
Tidak ada yang salah dengan cara Anda, kecuali jika Anda akan memiliki 100.000 loop dan ingin menyimpan 100.000 pernyataan "jika". Dalam hal ini, Anda dapat melakukannya:
Output:
Tapi sungguh, dalam kasusmu aku merasa itu berlebihan.
Bagaimanapun, Anda mungkin akan lebih beruntung dengan mengiris:
atau hanya :
Akhirnya, cara KISS untuk melakukan hal-hal Anda, dan itu akan bekerja dengan iterable, termasuk yang tanpa
__len__
:Ouputs:
Jika saya merasa akan melakukannya dengan cara itu, tampaknya sederhana bagi saya.
sumber
item
alih-alih menghitung ulang menggunakanlist[-1]
. Namun demikian: Saya kira ini bukan yang diminta OP, bukan?iterable.__iter__()
- tolong jangan panggil__
fungsi secara langsung. Seharusnyaiter(iterable)
.Gunakan irisan dan
is
untuk memeriksa elemen terakhir:Caveat emptor : Ini hanya berfungsi jika semua elemen dalam daftar sebenarnya berbeda (memiliki lokasi yang berbeda dalam memori). Di bawah tenda, Python dapat mendeteksi elemen yang sama dan menggunakan kembali objek yang sama untuk mereka. Misalnya, untuk string dengan nilai yang sama dan bilangan bulat umum.
sumber
jika Anda membaca daftar, bagi saya ini juga berfungsi:
sumber
Google membawa saya ke pertanyaan lama ini dan saya pikir saya bisa menambahkan pendekatan yang berbeda untuk masalah ini.
Sebagian besar jawaban di sini akan berurusan dengan perlakuan yang tepat untuk kontrol loop seperti yang ditanyakan, tetapi jika data_list dirusak, saya akan menyarankan agar Anda membuka item dari daftar sampai Anda berakhir dengan daftar kosong:
Anda bahkan dapat menggunakan saat len (element_list) jika Anda tidak perlu melakukan apa pun dengan elemen terakhir. Saya menemukan solusi ini lebih elegan daripada berurusan dengan next ().
sumber
Bagi saya cara paling sederhana dan pythonic untuk menangani kasus khusus di akhir daftar adalah:
Tentu saja ini juga dapat digunakan untuk memperlakukan elemen pertama dengan cara khusus.
sumber
Alih-alih menghitung, Anda juga dapat menghitung mundur:
sumber
Tunda penanganan khusus item terakhir hingga setelah putaran.
sumber
Mungkin ada beberapa cara. mengiris akan menjadi yang tercepat. Menambahkan satu lagi yang menggunakan metode .index ():
sumber
Mengasumsikan input sebagai iterator, inilah cara menggunakan tee dan izip dari itertools:
Demo:
sumber
Solusi paling sederhana yang muncul di pikiran saya adalah:
Jadi kami selalu melihat ke depan satu item dengan menunda pemrosesan satu iterasi. Untuk melewatkan melakukan sesuatu selama iterasi pertama saya cukup menangkap kesalahan.
Tentu saja Anda perlu berpikir sedikit, agar
NameError
dapat dinaikkan ketika Anda menginginkannya.Juga pertahankan counstruct
Ini bergantung pada nama baru yang sebelumnya tidak didefinisikan. Jika Anda paranoid, Anda dapat memastikan bahwa
new
tidak ada menggunakan:Atau Anda tentu saja dapat juga menggunakan pernyataan if (
if notfirst: print(new) else: notfirst = True
). Tapi sejauh yang saya tahu biaya overhead lebih besar.jadi saya berharap overhead tidak bisa dipilih.
sumber
Hitung item satu kali dan teruskan dengan jumlah item yang tersisa:
Dengan cara ini Anda hanya mengevaluasi panjang daftar sekali. Banyak solusi di halaman ini tampaknya menganggap panjangnya tidak tersedia sebelumnya, tetapi itu bukan bagian dari pertanyaan Anda. Jika Anda memiliki panjangnya, gunakan itu.
sumber
Salah satu solusi sederhana yang muncul dalam pikiran adalah:
Solusi kedua yang sama-sama sederhana dapat dicapai dengan menggunakan penghitung:
sumber