Перебирать словарь и изменять значения

Я пытаюсь изменить определенные значения datetime в dict на строки, рекурсивно повторяя его ключи.

from copy import deepcopy
def datetoStr2(datadict):
if 'dict' in str(type(datadict)):
    newdict = dict()
    newdict.update(datadict)
    for key in datadict:
        if isinstance(datadict[key], dict):
            newdict[key] = datetoStr(datadict[key])
        if isinstance(datadict[key], list):
            mylist = datadict[key]
            for element in mylist:
                element = datetoStr(element)
        if isinstance(datadict[key], datetime):
        #newdict[key] = datadict[key].strftime('%Y-%m-%d %H:%M:%S.%f%z')
            newdict[key] = str(datadict[key])
    return newdict
else:
    return datadict

Однако когда я бегу

some_dict = datetoStr(mydict)

У меня все еще есть объекты datetime на своих местах. Что я делаю неправильно?

Обновлено: обновленный код функции.

Эта функция была написана, потому что этот dict передается через jsonify Flask, который в настоящее время удаляет информацию о часовом поясе и заменяет ее на GMT. (Это планируется исправить в следующем обновлении).

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

Я также добавляю некоторые образцы данных и свои результаты.

Результат:

Быстрая печать, вставленная в код, говорит мне, что datetime остается datetime, а TZinfo удаляется jsonify.

Пример данных:

{'data': {'all': {'count': 2,
                  'data': [{'arrivalby': 'Wed, 20 Jun 2018 09:39:00 GMT',
                            'closesat': 'Wed, 20 Jun 2018 06:05:40 GMT',
                            'doctype': 'general',
                            'geofence': {'coordinates': [[[78.43786473803105,
                                                           17.447430456650043],
                                                          [78.45670406196896,
                                                           17.447430456650043],
                                                          [78.45670406196896,
                                                           17.46540214334996],
                                                          [78.43786473803105,
                                                           17.46540214334996],
                                                          [78.43786473803105,
                                                           17.447430456650043]]],
                                         'type': 'Polygon'},
                            'housecallid': '591ce42e9b53f96ea393934f61fab25d',
                            'lastupdated': 'Fri, 22 Jun 2018 04:32:14 GMT',
                            'requester': {'addr1': 'xxx xxx xx',
                                          'addr2': 'xx xx xx',
                                          'addr3': 'xx xx',
                                          'addrstate': 'xx',
                                          'city': 'xx',
                                          'dob': 'xx/xx/xxxx',
                                          'email': 'xx@xx',
                                          'fname': 'xxx',
                                          'lname': 'xx',
                                          'location': {'coordinates': [78.4472844,
                                                                       17.4564163],
                                                       'type': 'Point'},
                                          'mobile': xxxx,
                                          'sex': 'xxxx'},
                            'requesttime': 'Wed, 20 Jun 2018 00:05:40 GMT',
                            'responder': {'addr1': 'xxx xxxx',
                                          'addr2': 'xx xx xxxx',
                                          'addr3': 'xxx xx',
                                          'addrstate': 'xxxx',
                                          'city': 'xxxx',
                                          'email': 'xx@xxxx',
                                          'fname': 'xxxx',
                                          'lname': 'xxxx',
                                          'location': {'coordinates': [78.4471904,
                                                                       17.456458],
                                                       'type': 'Point'},
                                          'mobile': xxxx,
                                          'sex': 'xxxx'},
                            'responsetime': 'Wed, 20 Jun 2018 00:09:37 GMT',
                            'status': 'missed'},
                           {'arrivalby': 'Sat, 23 Jun 2018 10:13:00 GMT',
                            'closesat': 'Fri, 22 Jun 2018 10:42:11 GMT',
                            'doctype': 'general',
                            'geofence': {'coordinates': [[[78.43784273760974,
                                                           17.44743855664762],
                                                          [78.45668206239024,
                                                           17.44743855664762],
                                                          [78.45668206239024,
                                                           17.465410243352377],
                                                          [78.43784273760974,
                                                           17.465410243352377],
                                                          [78.43784273760974,
                                                           17.44743855664762]]],
                                         'type': 'Polygon'},
                            'housecallid': '998987171790f172b97a7981a8902af1',
                            'lastupdated': 'Fri, 22 Jun 2018 18:36:50 GMT',
                            'requester': {'addr1': 'xx xxx, ',
                                          'addr2': 'xx xx xxxx',
                                          'addr3': 'xxx xxx',
                                          'addrstate': 'xx',
                                          'city': 'xxxx',
                                          'dob': 'xxxx-xx-xx',
                                          'email': 'xxxx@xxxx',
                                          'fname': 'xx',
                                          'lname': 'xx',
                                          'location': {'coordinates': [78.4472624,
                                                                       17.4564244],
                                                       'type': 'Point'},
                                          'mobile': xxxx,
                                          'sex': 'xxxx'},
                            'requesttime': 'Fri, 22 Jun 2018 04:42:11 GMT',
                            'responder': {'addr1': 'xxxx xxxx',
                                          'addr2': 'xx xx xx',
                                          'addr3': 'xxxx xxxx',
                                          'addrstate': 'xxxx',
                                          'city': 'xxxx',
                                          'email': 'xxx@xxxx',
                                          'fname': 'xxxxx',
                                          'lname': 'xxxx',
                                          'location': {'coordinates': [78.4471904,
                                                                       17.456458],
                                                       'type': 'Point'},
                                          'mobile': xxxx,
                                          'sex': 'xx'},
                            'responsetime': 'Fri, 22 Jun 2018 04:43:05 GMT',
                            'status': 'missed'}]},
          'cancelled': {'count': 0, 'data': []},
          'closed': {'count': 0, 'data': []},
          'confirmed': {'count': 0, 'data': []},
          'missed': {'count': 2,
                     'data': [{'arrivalby': 'Wed, 20 Jun 2018 09:39:00 GMT',
                               'closesat': 'Wed, 20 Jun 2018 06:05:40 GMT',
                               'doctype': 'general',
                               'geofence': {'coordinates': [[[78.43786473803105,
                                                              17.447430456650043],
                                                             [78.45670406196896,
                                                              17.447430456650043],
                                                             [78.45670406196896,
                                                              17.46540214334996],
                                                             [78.43786473803105,
                                                              17.46540214334996],
                                                             [78.43786473803105,
                                                              17.447430456650043]]],
                                            'type': 'Polygon'},
                               'housecallid': '591ce42e9b53f96ea393934f61fab25d',
                               'lastupdated': 'Fri, 22 Jun 2018 04:32:14 GMT',
                               'requester': {'addr1': 'xx xx xxx',
                                             'addr2': 'xx xx xxxx',
                                             'addr3': 'xx xx',
                                             'addrstate': 'xxxxxx',
                                             'city': 'xxxxx',
                                             'dob': 'xx/xx/xxxx',
                                             'email': 'xx@xxx',
                                             'fname': 'xx',
                                             'lname': 'xxx',
                                             'location': {'coordinates': [78.4472844,
                                                                          17.4564163],
                                                          'type': 'Point'},
                                             'mobile': xx,
                                             'sex': 'xx'},
                               'requesttime': 'Wed, 20 Jun 2018 00:05:40 GMT',
                               'responder': {'addr1': 'xx xx',
                                             'addr2': 'xx xx xxxx',
                                             'addr3': 'xx xx',
                                             'addrstate': 'xx',
                                             'city': 'xx',
                                             'email': 'xx@xx',
                                             'fname': 'xx',
                                             'lname': 'xx',
                                             'location': {'coordinates': [78.4471904,
                                                                          17.456458],
                                                          'type': 'Point'},
                                             'mobile': xxxx,
                                             'sex': 'xx'},
                               'responsetime': 'Wed, 20 Jun 2018 00:09:37 GMT',
                               'status': 'missed'},
                              {'arrivalby': 'Sat, 23 Jun 2018 10:13:00 GMT',
                               'closesat': 'Fri, 22 Jun 2018 10:42:11 GMT',
                               'doctype': 'general',
                               'geofence': {'coordinates': [[[78.43784273760974,
                                                              17.44743855664762],
                                                             [78.45668206239024,
                                                              17.44743855664762],
                                                             [78.45668206239024,
                                                              17.465410243352377],
                                                             [78.43784273760974,
                                                              17.465410243352377],
                                                             [78.43784273760974,
                                                              17.44743855664762]]],
                                            'type': 'Polygon'},
                               'housecallid': '998987171790f172b97a7981a8902af1',
                               'lastupdated': 'Fri, 22 Jun 2018 18:36:50 GMT',
                               'requester': {'addr1': 'xxx xxx, ',
                                             'addr2': 'xx xx xxxx',
                                             'addr3': 'xx xx',
                                             'addrstate': 'xxx',
                                             'city': 'xxx',
                                             'dob': 'xxxx-xx-xx',
                                             'email': 'xxxx@xxxx',
                                             'fname': 'xx',
                                             'lname': 'xx',
                                             'location': {'coordinates': [78.4472624,
                                                                          17.4564244],
                                                          'type': 'Point'},
                                             'mobile': xxxxx,
                                             'sex': 'xx'},
                               'requesttime': 'Fri, 22 Jun 2018 04:42:11 GMT',
                               'responder': {'addr1': 'xx xx',
                                             'addr2': 'xx xx xxxx',
                                             'addr3': 'xx xx',
                                             'addrstate': 'xx',
                                             'city': 'xxxx',
                                             'email': 'xxxx@xxxx',
                                             'fname': 'xx',
                                             'lname': 'xx',
                                             'location': {'coordinates': [78.4471904,
                                                                          17.456458],
                                                          'type': 'Point'},
                                             'mobile': xx,
                                             'sex': 'xxxx'},
                               'responsetime': 'Fri, 22 Jun 2018 04:43:05 GMT',
                               'status': 'missed'}]}},  'success': True}

ОБНОВЛЕНИЕ - 24 июня 2018 г.

Спасибо, Патрик, за ответ. Я принял его как правильный.

Однако в своей редакции я говорил о том, что список является элементом, и поэтому я добавил следующий код (для тех, кто ищет способ обойти ошибку jsonify).

def datetoStr(datadict):
    from copy import deepcopy
    # deepcopy before data manipulation
    if 'dict' in str(type(datadict)):
        newdict = deepcopy(datadict)

        for key,value in datadict.items():
            # recurse into nested dicts
            if isinstance(value, dict):
                newdict[key] = datetoStr(datadict[key])
            # convert to string
            elif isinstance(value, datetime):
                newdict[key] = str(datadict[key])
            # if list, iterate through elements and replace
            elif isinstance(datadict[key], list):
                newlist = datadict[key].copy()
                counter = 0
                for element in datadict[key]:
                    newlist[counter] = datetoStr(datadict[key][counter])
                    counter += 1
                newdict[key] = newlist
        return newdict
    else:
        return datadict

К вашему сведению, обычный способ проверить, является ли значение определенным типом, - это type(datadict[key]) is datetime или, если подклассы в порядке, isinstance(datadict[key], datetime).

jwodder 23.06.2018 23:43

Можете ли вы привести пример входных данных и желаемого результата? На самом деле нам нужен минимальный воспроизводимый пример, чтобы быть уверенным, что мы решили вашу проблему.

jpp 23.06.2018 23:46

@jpp - добавленные данные и результат, который я получил.

kilokahn 24.06.2018 00:38
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
4 321
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете немного упростить свой код, если используете dict.items(), который дает вам ключи и значения для итерации напрямую:

from copy import deepcopy
import datetime 

def datetoStr(datadict):
    # deepcopy before data manipulation
    newdict = deepcopy(datadict)

    for key,value in datadict.items():
        # recurse into nested dicts
        if isinstance(value, dict):
            newdict[key] = datetoStr(datadict[key])
        # convert to string
        elif isinstance(value, datetime.datetime): 
            newdict[key] = str(datadict[key])

    return newdict


before = { "a date": datetime.datetime.now(),
           "a dict": { "another": datetime.datetime.now() + datetime.timedelta(hours=2)}}

print(before)

# get the modified copy of before
transformedDict = datetoStr(before) 
print(transformedDict)

Выход:

# before        
{'a date': datetime.datetime(2018, 6, 23, 21, 54, 12, 806419), 
 'a dict': {'another': datetime.datetime(2018, 6, 23, 23, 54, 12, 806421)}}

# transformedDict
{'a date': '2018-06-23 21:54:12.806419', 
 'a dict': {'another': '2018-06-23 23:54:12.806421'}}

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