Saya memiliki kode berikut untuk melakukan ini, tetapi bagaimana saya bisa melakukannya dengan lebih baik? Saat ini saya pikir ini lebih baik daripada loop bersarang, tetapi mulai mendapatkan Perl-one-linerish ketika Anda memiliki generator dalam daftar pemahaman.
day_count = (end_date - start_date).days + 1
for single_date in [d for d in (start_date + timedelta(n) for n in range(day_count)) if d <= end_date]:
print strftime("%Y-%m-%d", single_date.timetuple())
Catatan
- Saya sebenarnya tidak menggunakan ini untuk mencetak. Itu hanya untuk keperluan demo.
- The
start_date
danend_date
variabeldatetime.date
benda karena saya tidak perlu cap waktu. (Mereka akan digunakan untuk menghasilkan laporan).
Output Sampel
Untuk tanggal mulai 2009-05-30
dan tanggal akhir 2009-06-09
:
2009-05-30
2009-05-31
2009-06-01
2009-06-02
2009-06-03
2009-06-04
2009-06-05
2009-06-06
2009-06-07
2009-06-08
2009-06-09
Jawaban:
Mengapa ada dua iterasi bersarang? Bagi saya itu menghasilkan daftar data yang sama dengan hanya satu iterasi:
Dan tidak ada daftar yang disimpan, hanya satu generator yang diulang. Juga "jika" di generator tampaknya tidak perlu.
Lagipula, urutan linear seharusnya hanya membutuhkan satu iterator, bukan dua.
Pembaruan setelah diskusi dengan John Machin:
Mungkin solusi yang paling elegan adalah menggunakan fungsi generator untuk sepenuhnya menyembunyikan / mengabstraksi iterasi pada rentang tanggal:
NB: Untuk konsistensi dengan
range()
fungsi bawaan iterasi ini berhenti sebelum mencapaiend_date
. Jadi untuk iterasi inklusif gunakan hari berikutnya, seperti yang Anda lakukan denganrange()
.sumber
(start_date + datetime.timedelta(n) for n in range((end_date - start_date).days))
Ini mungkin lebih jelas:
sumber
Gunakan
dateutil
perpustakaan:Pustaka python ini memiliki banyak fitur canggih, beberapa sangat berguna, seperti
relative delta
s — dan diimplementasikan sebagai satu file (modul) yang mudah dimasukkan ke dalam proyek.sumber
until
sedangkan tanggal akhir daridaterange
metode dalam jawaban Ber ini adalah eksklusif dariend_date
.Panda bagus untuk deret waktu secara umum, dan memiliki dukungan langsung untuk rentang tanggal.
Anda kemudian dapat mengulangi daterange untuk mencetak tanggal:
Ini juga memiliki banyak pilihan untuk membuat hidup lebih mudah. Misalnya, jika Anda hanya menginginkan hari kerja, Anda cukup menukar di bdate_range. Lihat http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps
Kekuatan Pandas adalah benar-benar kerangka datanya, yang mendukung operasi vektor (seperti numpy) yang membuat operasi melintasi sejumlah besar data sangat cepat dan mudah.
EDIT: Anda juga bisa melewatkan loop untuk dan hanya mencetaknya secara langsung, yang lebih mudah dan lebih efisien:
sumber
Fungsi ini melakukan lebih dari yang Anda perlukan, dengan mendukung langkah negatif, dll. Selama Anda memfaktorkan logika jangkauan Anda, maka Anda tidak perlu terpisah
day_count
dan yang paling penting kode menjadi lebih mudah dibaca saat Anda memanggil fungsi dari banyak tempatsumber
Ini adalah solusi yang paling bisa dibaca manusia yang bisa saya pikirkan.
sumber
Kenapa tidak mencoba:
sumber
Fungsi Numpy
arange
dapat diterapkan ke tanggal:Penggunaan
astype
is untuk mengkonversi darinumpy.datetime64
ke arraydatetime.datetime
objek.sumber
dates = np.arange(d0, d1, dt).astype(datetime.datetime)
Perlihatkan n hari terakhir mulai hari ini:
Keluaran:
sumber
print((datetime.date.today() + datetime.timedelta(i)).isoformat())
print((datetime.date.today() + datetime.timedelta(i)))
tanpa .isoformat () memberikan output yang persis sama. Saya perlu skrip saya untuk mencetak YYMMDD. Ada yang tahu bagaimana melakukan hal itu?d = datetime.date.today() + datetime.timedelta(i); d.strftime("%Y%m%d")
sumber
sumber
Untuk kelengkapan, Pandas juga memiliki
period_range
fungsi untuk cap waktu yang di luar batas:sumber
Saya memiliki masalah yang sama, tetapi saya harus mengulanginya setiap bulan, bukan setiap hari.
Ini solusi saya
Contoh 1
Keluaran
Contoh # 2
Keluaran
sumber
Dapat
't* percaya pertanyaan ini telah ada selama 9 tahun tanpa ada yang menyarankan fungsi rekursif sederhana:Keluaran:
Sunting: * Sekarang saya dapat mempercayainya - lihat Apakah Python mengoptimalkan rekursi ekor? . Terima kasih, Tim .
sumber
Anda dapat menghasilkan serangkaian tanggal antara dua tanggal menggunakan perpustakaan panda secara sederhana dan penuh kepercayaan
Anda dapat mengubah frekuensi menghasilkan tanggal dengan menetapkan freq sebagai D, M, Q, Y (harian, bulanan, triwulanan, tahunan)
sumber
sumber
Fungsi ini memiliki beberapa fitur tambahan:
memeriksa kesalahan jika akhirnya lebih tua dari awal
sumber
Berikut kode untuk fungsi rentang tanggal umum, mirip dengan jawaban Ber, tetapi lebih fleksibel:
sumber
Bagaimana dengan yang berikut untuk melakukan rentang yang bertambah berdasarkan hari:
Untuk versi generik:
Perhatikan bahwa .total_seconds () hanya didukung setelah python 2.7. Jika Anda terjebak dengan versi sebelumnya, Anda dapat menulis fungsi Anda sendiri:
sumber
Pendekatan yang sedikit berbeda untuk langkah reversibel dengan menyimpan
range
args dalam tuple.sumber
KELUARAN:
sumber