Найти в словаре ключи с наибольшей датой по маскам

Как я могу получить ключи из словаря ftp_json с самой большой датой по маске из списка daily_updated?

daily_updated = ('kgrd', 'cvhd', 'metd')

ftp_json = {'kgrd0118.arj': 'Jan-18-2007', 
 'kgrd0623.arj': 'Jun-23-2005', 
 'kgrd0624.arj': 'Jun-24-2005', 
 'cvhd0629.ARJ': 'Jan-29-2021', 
 'cvhd1026.arj': 'Oct-26-2015', 
 'cvhd1125.ARJ': 'Nov-25-2019', 
 'cvhd0222.ARJ': 'Feb-22-2022',
 'metd0228.ARJ': 'Feb-28-2022',
 'metd0321.ARJ': 'Mar-26-2021',
}


result = ['kgrd0118.arj', 'cvhd0222.arj', 'metd0228.ARJ']

Что вы имеете в виду под маской? Маска обычно относится к последовательности битов, используемых для побитовых операций, но ваши данные — это все строки, а не целые числа.

Nick Bailey 22.03.2022 16:54

Я имею в виду, что "маска" = значение в списке daily_updated. Например, значение «kgrd» в ftp_json включает дату в конце имени («krgd0102», «krgd0103» и т. д.). Моя маска в примере — «krgd».

ChainSaw 22.03.2022 17:08

«маска» - это только первые 4 символа ключа?

JonSG 22.03.2022 17:09

Да, маска - это только первые 4 символа ключа.

ChainSaw 22.03.2022 17:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
58
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

используя numpy.argmax и pandas.to_datetime:

import numpy as np

result = []
for d in daily_updated:
    a = [(key,date) for key, date in ftp_json.items() if d in key]
    index = np.argmax([pd.to_datetime(date) for key,date in a])
    result.append(a[index][0])

Было бы хорошо указать, что это решение использует стороннюю библиотеку, которую необходимо установить и импортировать.

theherk 22.03.2022 17:05

Я думаю, это библиотека numpy

ChainSaw 22.03.2022 17:17
Ответ принят как подходящий

Без сомнения, это можно сделать проще, но я думаю, что этот пример является наглядным способом сделать это со стандартной библиотекой.

from datetime import datetime

ftp_json = {
    "kgrd0118.arj": "Jan-18-2007",
    "kgrd0623.arj": "Jun-23-2005",
    "kgrd0624.arj": "Jun-24-2005",
    "cvhd0629.ARJ": "Jan-29-2021",
    "cvhd1026.arj": "Oct-26-2015",
    "cvhd1125.ARJ": "Nov-25-2019",
    "cvhd0222.ARJ": "Feb-22-2022",
    "metd0228.ARJ": "Feb-28-2022",
    "metd0321.ARJ": "Mar-26-2021",
}


max_dates = {}  # New dict for storing running maximums.
for k, v in ftp_json.items():
    d = datetime.strptime(v, "%b-%d-%Y")  # Use datetime for comparison.
    # Here we return the previous tuple values if set for comparison.
    # If they weren't set, do so now.
    maxk, maxv, maxd = max_dates.setdefault(k[:4], (k, v, d))
    if d > maxd:  # Update the values is the current date is more recent.
        max_dates[k[:4]] = (k, v, d)

# Validate we stored the correct values.
assert [v[0] for v in max_dates.values()] == [
    "kgrd0118.arj",
    "cvhd0222.ARJ",
    "metd0228.ARJ",
]

Спасибо, очень просто и понятно для меня.

ChainSaw 23.03.2022 07:59

Вы можете воспользоваться параметром key встроенной функции maxmin), чтобы наложить критерий упорядочения. Перед этим вам нужно превратить строку, содержащую даты, в объекты datetime, которые поставляются вместе со своим собственным порядком, __lt__ и т. д., реализацией. Здесь документ для форматирования даты.

Обратите внимание, что необходим минимальный объект date, он будет использоваться как «фальшивое» значение, чтобы избежать помех от всех других масок в поиске максимального термина. Я, естественно, зафиксировал его как минимум среди всех дат.

import datetime

daily_updated = ('kgrd', 'cvhd', 'metd')

ftp_json = {'kgrd0118.arj': 'Jan-18-2007',
 'kgrd0623.arj': 'Jun-23-2005',
 'kgrd0624.arj': 'Jun-24-2005',
 'cvhd0629.ARJ': 'Jan-29-2021',
 'cvhd1026.arj': 'Oct-26-2015',
 'cvhd1125.ARJ': 'Nov-25-2019',
 'cvhd0222.ARJ': 'Feb-22-2022',
 'metd0228.ARJ': 'Feb-28-2022',
 'metd0321.ARJ': 'Mar-26-2021',
}


def date_formatter(mydate):
    return datetime.datetime.strptime(mydate, '%b-%d-%Y').date()

# smallest date
day_zero = datetime.datetime.strptime(min(ftp_json.values(), key=lambda d: date_formatter(d)), '%b-%d-%Y').date()

# get the maximum for each mask
m = [max(ftp_json.items(), key=lambda pair: date_formatter(pair[1]) if pair[0].startswith(pattern) else day_zero) for pattern in daily_updated]

print([i for i, _ in m])

Выход

['kgrd0118.arj', 'cvhd0222.ARJ', 'metd0228.ARJ']

РЕДАКТИРОВАТЬ

Чтобы сделать его более читабельным (а не однострочным), можно ввести декоратор, который будет передаваться в параметр keymax (min).

# ...

def date_formatter(mydate):
    return datetime.datetime.strptime(mydate, '%b-%d-%Y').date()

# smallest date
day_zero = datetime.datetime.strptime(min(ftp_json.values(), key=lambda d: date_formatter(d)), '%b-%d-%Y').date()

# decorator containing the logic of the comparison criteria
def ordering(pattern):
    def _wrapper(pair):
        if pair[0].startswith(pattern):
            # cast to date-object if the "mask"/pattern is correct 
            return date_formatter(pair[1])
        else:
            # return default smallest date-object -> will not influence the max-function
            return day_zero
    return _wrapper

# get the maximum for each mask
m = [max(ftp_json.items(), key=ordering(pattern)) for pattern in daily_updated]

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

Факел model.load_state_dict *** AttributeError: объект «ModelName» не имеет атрибута «копия»
В python, если пользователь вводит строку вместо числа (целочисленное значение), то как мы можем показать пользователю сообщение о том, что ввод недействителен?
Расширение CPython с использованием omp замораживает пользовательский интерфейс Qt
Эффективная проверка целочисленных кортежей на наличие двоичных условий
Найдите минимальную плоскость максимального количества черных пикселей на нижнем изображении. Найдите пик черных пикселей для верхнего изображения
Python/Tkinter: нежелательное взаимодействие между двумя виджетами
ValueError: данные времени «14.03.2022 00:00:00.000 GMT-0400» не соответствуют формату «%d.%m.%Y %H:%M:%S.%f %z» (совпадение)
Найти два слова в строке, разделенные неизвестным количеством символов, регулярное выражение, python
Возникла проблема при извлечении номера версии из pom с использованием xPath
Как разбить 2d-массив в python?