Сравните любое количество дат в списке внутри словаря

У меня есть словарь таких дат (ключи здесь относятся к другой работе и их нужно учитывать):

{2: ['8-12-2012', '9-12-2012', '7-12-2012],
 5: ['10-12-2012', '11-12-2012'],
 7: ['13-12-2012']}

Теперь я хочу найти самую раннюю дату в каждом списке. В конце концов, мне нужно выяснить, какая дата была самой ранней, вернув эту дату и ключ.

Если я вручную проделаю то, что пытаюсь сделать здесь:

**key 2**, `7-12-2012` is the earliest.
**key 5**, `10-12-2012` is the earliest.
**key 7**, `13-12-2012` is the earliest.

7-12-2012 - самая ранняя дата, поэтому мне следует вернуть 2.

Здесь следует отметить:

  1. Данные в словаре создаются динамически во время выполнения.
  2. списки внутри словаря не фиксированной длины.

Это то, что я пробовал, но сравнивал только две даты:

...
...
# this value would be dynamically set during runtime
expiryDates[item] = {2: ['8-12-2012', '9-12-2012', '7-12-2012], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}

datesInBox = []
dict_earliest_expiration = defaultdict(list)

for n in expiryDates:
    datesInBox = expiryDates[n] # when n = 2; datesInBox = ['8-12-2012', '9-12-2012']
    d1 = time.strptime(datesInBox[0], "%d-%m-%Y")
    d2 = time.strptime(datesInBox[1], "%d-%m-%Y")
    if d1 < d2:
        dict_earliest_expiration[n] = d1
    else:
        dict_earliest_expiration[n] = d2

Любая помощь будет принята с благодарностью.

1
0
46
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Переберите свой dict или передайте ключ напрямую. Преобразуйте список в серию панд и отсортируйте его

import pandas as pd
d={2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}

for key,value in d.items():
    print(key,pd.to_datetime(pd.Series(value)).sort_values().iloc[0])

Выход

(2, Timestamp('2012-07-12 00:00:00'))
(5, Timestamp('2012-10-12 00:00:00'))
(7, Timestamp('2012-12-13 00:00:00'))

Если вас интересуют только даты

for key,value in d.items():
    print(key,pd.to_datetime(pd.Series(value)).dt.date.sort_values().iloc[0])

Выход:

(2, datetime.date(2012, 7, 12))
(5, datetime.date(2012, 10, 12))
(7, datetime.date(2012, 12, 13))

Представление даты в соответствии с приведенным примером

for key,value in d.items():
    print('key: {}, Earliest Date: {} '.format(key,pd.to_datetime(pd.Series(value)).dt.date.sort_values().iloc[0].strftime("%m-%d-%Y")))

Выход:

key: 2, Earliest Date: 07-12-2012 
key: 5, Earliest Date: 10-12-2012 
key: 7, Earliest Date: 12-13-2012 

Я буду работать над этим медленно, чтобы вы могли увидеть процесс. Во-первых, переверните диктант: используйте время как ключ, предыдущий ключ как значение:

exp = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
rev = []

for key, val_list in exp.items():
    for val in val_list:
        rev[time.strptime(val, "%d-%m-%Y")] = key

Очистив представление, теперь rev

{
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday=13): 7, 
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 8): 2, 
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 7): 2, 
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 9): 2, 
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday=11): 5, 
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday=10): 5
}

Теперь достаточно просто распечатать ключ в самое раннее время:

>>> rev[min(rev)]
2

Если хотите, вы можете свернуть это в понимание слов и тривиальный вызов.

Я все время получаю «NameError: имя 'rev' не определено». Пытался погуглить, но безрезультатно. Было ли что-то выше значения опыта?

SKS 13.09.2018 21:05

Отрубил строку инициализации. Мои извенения. Исправлено сейчас.

Prune 13.09.2018 21:17
Ответ принят как подходящий

Вы можете преобразовать все строки на сегодняшний день, а затем использовать функцию мин:

import time

data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
d2 = {k: [time.strptime(e, "%d-%m-%Y") for e in v] for k, v in data.items()}
print(min(d2, key=lambda e: min(d2[e])))

Выход

2

В качестве альтернативы вы можете предварительно вычислить минимум для каждого ключа словаря:

data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
d2 = {k: min(time.strptime(e, "%d-%m-%Y") for e in v) for k, v in data.items()}
print(min(d2, key=lambda e: d2[e]))

Выход

2

Наконец, вместо того, чтобы перебирать ключи, вы можете перебирать пары ключей и значений:

data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
d2 = {k: min(time.strptime(e, "%d-%m-%Y") for e in v) for k, v in data.items()}
print(min(d2.items(), key=lambda t: t[1])[0])

Выход

2

Другие вопросы по теме