Преобразование всех словарей из списка Python

У меня есть список словарей с датами. Я написал код функции, которая должна преобразовать дату в нужный мне формат. Если словарь один, то функция работает так как надо:

import datetime
days = {'date': '2010-08-07T19:36:14.672617'}


def all_date(days):
    days['date'] = datetime.datetime.fromisoformat(days['date'])
    day_x = datetime.datetime.strftime(days['date'], '%d.%m.%Y')
    return day_x

print(all_date(days))

Результат:

07.08.2010

Если я подставляю список словарей, то возникает ошибка:

TypeError: list indices must be integers or slices, not str

Я переписал код, но в результате только первая дата:

import datetime
days = [{'date': '2010-08-07T19:36:14.672617'}, {'date': '2015-08-07T19:36:14.672617'}, {'date': '2020-08-07T19:36:14.672617'}]

def all_date(days):
    for i in range(len(days)): 
        days[i]['date'] = datetime.datetime.fromisoformat(days[i]['date'])
        day_x = datetime.datetime.strftime(days[i]['date'], '%d.%m.%Y')
        return day_x

print(all_date(days)

Сейчас я получаю:

07.08.2010

А надо получить:

07.08.2010
07.08.2015
07.08.2020

Как это правильно сделать?


Ответы (2 шт):

Автор решения: Sergey K.

Потому что ты возвращаешь return day_x, то есть, первую преобразованную дату. Тебе следует создать список, в него в цикле складывать свои day_x, а потом уже его вернуть. Как-то так:

def all_date(days):
    # это список, где будут сохраняться даты
    result = []
    for i in range(len(days)): 
        days[i]['date'] = datetime.datetime.fromisoformat(days[i]['date'])
        day_x = datetime.datetime.strftime(days[i]['date'], '%d.%m.%Y')
        # вместо return добавляем его в список
        result.add(day_x)
  # возвращаем в итоге список всех дат
  return result

При этом, цикл можно оптимизировать. Цикл for умеет перебирать коллекции, без обращения к индексу. for o in days

Функция будет выглядеть так:

def all_date(days):
    # это список, где будут сохраняться даты
    result = []
    for o in days: 
        o['date'] = datetime.datetime.fromisoformat(o['date'])
        day_x = datetime.datetime.strftime(o['date'], '%d.%m.%Y')
        # вместо return добавляем его в список
        result.add(day_x)
  # возвращаем в итоге список всех дат
  return result
→ Ссылка
Автор решения: Andy Pavlov

Все можно сделать в одну строку, поскольку метод strftime() применим к объекту datetime, создаваемый через datetime.datetime.fromisoformat(). В результате все делается за один проход.

В итоге в цикле подаваемый список словарей обрабатываем строкой с двойным преобразованием datetime.datetime.fromisoformat(d['date']).strftime('%d.%m.%Y')

import datetime

def all_date(days):
    return [datetime.datetime.fromisoformat(d['date']).strftime('%d.%m.%Y') for d in days]

days = [{'date': '2010-08-07T19:36:14.672617'}, {'date': '2015-08-07T19:36:14.672617'}, {'date': '2020-08-07T19:36:14.672617'}]

print(*all_date(days), sep='\n')

Вывод:

07.08.2010
07.08.2015
07.08.2020
→ Ссылка