Tujuan saya adalah untuk mendapatkan tanggal terdekat berikutnya (di masa depan, bukan masa lalu) ke tanggal hari ini dari daftar. Demi kesederhanaan, daftar (dalam format mis. 2017-01-31; YYYY-MM-DD) adalah setiap pertandingan sepak bola di musim ini dan saya mencoba membuat skrip yang sebagian menemukan pertandingan sepak bola "berikutnya".

Saya telah mencari jawaban di internet dan Stack Overflow dan menemukan postingan yang menjanjikan, namun solusi yang diberikan menggunakan format dan ketika saya mencoba menyesuaikannya dengan milik saya, itu membuat pengecualian.

Logika saya mencakup penguraian umpan RSS, jadi saya hanya akan memberikan daftar mentah saja. Dengan mengingat hal ini, kode saya yang disederhanakan adalah sebagai berikut:

today = str(datetime.date.today())
print(today)

scheduledatelist = ['2017-09-01', '2017-09-09', '2017-09-16', '2017-09-23', '2017-09-30', '2017-10-07', '2017-10-14', '2017-10-21', '2017-10-27', '2017-11-11', '2017-11-18', '2017-11-25']
scheduledatelist = list(reversed(scheduledatelist)) #purpose: to have earliest dates first

Ini adalah upaya saya untuk mengadaptasi solusi posting sebelumnya (saya tidak berpengalaman dalam pemrograman fungsional, jadi saya mungkin tidak mengadaptasinya dengan benar):

get_datetime = lambda s: datetime.datetime.strptime(s, "%Y-%m-%d")
base = get_datetime(today)
later = filter(lambda d: today(d[0]) > today, scheduledatelist)
closest_date = min(later, key = lambda d: today(d[0]))
print(closest_date)

Terlepas dari upaya saya (yang mungkin bukan yang terbaik dalam situasi saya karena mengubah format dan saya perlu nilai akhir tetap YYYY-MM-DD), apakah ada cara yang lebih mudah untuk melakukan ini? Saya membutuhkan nilai game berikutnya (paling dekat dengan hari ini) karena itu akan terus digunakan dalam logika saya. Jadi untuk rekap, bagaimana saya bisa menemukan tanggal terdekat dalam daftar saya, melihat ke masa depan, mulai hari ini. Terima kasih untuk bantuannya!

1
J. Squillaro 7 Agustus 2017, 18:40

2 jawaban

Jawaban Terbaik

Anda dapat melakukan:

min(scheduledatelist, key=lambda s: 
                  datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())

Untuk satu tanggal terdekat dengan hari ini.

Anda dapat menggunakan fungsi yang sama untuk mengurutkan berdasarkan jarak mulai hari ini:

sorted(scheduledatelist, key=lambda s: 
              datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())

Dan daftar yang dikembalikan akan semakin jauh dalam beberapa hari dari hari ini. Berfungsi jika tanggalnya sebelum atau sesudah hari ini.

Jika Anda hanya ingin tanggal di masa mendatang, filter tanggal di masa lalu. Karena string tanggal dalam format ISO 8601, Anda dapat membandingkan secara leksikal:

min([d for d in scheduledatelist if d>str(datetime.date.today())], key=lambda s: 
              datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())
2
dawg 7 Agustus 2017, 16:59

Pertama-tama mari kita buat objek datetime.date dari string menggunakan datetime.datetime.strptime dan datetime.datetime.date metode karena objek datetime.date diurutkan dan lebih mudah digunakan:

date_format = '%Y-%m-%d'
dates = [datetime.datetime.strptime(date_string,
                                    date_format).date()

Lalu mari kita saring tanggal yang terjadi di masa depan (setelah hari ini)

today = datetime.date.today()
future_dates = [date
                for date in dates
                if date >= today]

Maka kita cukup menemukan tanggal terdekat berikutnya menggunakan min

next_closest_date = min(future_dates)

Yang memberi kita

>>>next_closest_date
2017-09-01

Untuk contoh yang diberikan


PERINGATAN

Jika tidak ada tanggal setelah hari ini, ini akan menyebabkan kesalahan seperti

ValueError: min() arg is an empty sequence

Jika tidak apa-apa maka kita dapat meninggalkannya, tetapi jika kita tidak ingin mendapatkan kesalahan – kita dapat menentukan nilai default untuk min jika urutan kosong seperti

next_closest_date = min(future_dates, default=None)

Akhirnya kita dapat menulis fungsi sebagai berikut:

import datetime


# `default` value is returned when there is no future date strings found
def get_next_closest_date(date_strings, date_format, default=None):
    today = datetime.date.today()
    dates = [datetime.datetime.strptime(date_string,
                                        date_format).date()
             for date_string in date_strings]
    future_dates = [date
                    for date in dates
                    if date >= today]
    return min(future_dates, default)

Dan gunakan seperti

scheduledatelist = ['2017-09-01', '2017-09-09', '2017-09-16', '2017-09-23',
                    '2017-09-30', '2017-10-07', '2017-10-14', '2017-10-21',
                    '2017-10-27', '2017-11-11', '2017-11-18', '2017-11-25']
next_closest_date = get_next_closest_date(date_strings=scheduledatelist,
                                          date_format='%Y-%m-%d')
print(next_closest_date)
2
Azat Ibrakov 7 Agustus 2017, 16:10