参数有2个字典:
fb_config = {
"page_likes" : {
"page_id": "1111",
"metric": "page_fans",
"since": "2019-01-01 00:00:00",
"until": "2019-01-01 00:00:00",
"date_preset" : "yesterday",
"period": "day"},
"page_impressions" : {"page_id": "1111",
"metric": "page_impressions",
"since": "yesterday",
"until": "yesterday",
"date_preset" : "yesterday",
"period": "day"},
"page_engaged_users" : {"page_id": "1111",
"metric": "page_engaged_users",
"since": "today",
"until": "today",
"date_preset" : "yesterday",
"period": "day"}}
和
ga_config =
{
'view_id_123': {'view_id': '123',
'start_date': "2019-01-01 00:00:00",
'end_date': "2019-01-01 00:00:00",
'metrics': [{'expression': 'ga:sessions'}, {'expression':'ga:pageviews'}, {'expression':'ga:users'}, {'expression':'ga:bounces'},
{'expression':'ga:avgSessionDuration'}],
'dimensions': [{'name': 'ga:year'}, {'name': 'ga:userType'}, {'name': 'ga:sessionCount'}, {'name': 'ga:browser'},
{'name': 'ga:source'}]},
'view_id_456': {'view_id': '456',
'start_date': "today",
'end_date': "today",
'metrics': [{'expression': 'ga:bounces'}, {'expression':'ga:users'}],
'dimensions': [{'name': 'ga:mobileDeviceModel'}, {'name': 'ga:dataSource'}]},
'view_id_789': {'view_id': '789',
'start_date': "yesterday",
'end_date': "yesterday",
'metrics': [{'expression': 'ga:bounces'}, {'expression':'ga:users'}],
'dimensions': [{'name': 'ga:mobileDeviceModel'}, {'name': 'ga:dataSource'}]}
}
在代码中,我无法保留参数,而是想从json文件中提取它们。加载文件后,所有日期都必须从str转换为datetime格式。
此过程通过以下几个循环完成:
for values in params.values():
if 'since' in values:
if values['since'] == 'today':
values['since'] = datetime.now()
elif values['since'] == 'yesterday':
values['since'] = datetime.now() - timedelta(1)
else:
values['since'] = dt.datetime.strptime(values['since'], '%Y-%m-%d %H:%M:%S')
for values in params.values():
if 'until' in y:
if values['until'] == 'today':
values['until'] = datetime.now()
elif values['until'] == 'yesterday':
values['until'] = datetime.now() - timedelta(1)
else:
values['until'] = dt.datetime.strptime(y['until'], '%Y-%m-%d %H:%M:%S')
for values in params.values():
if 'start_date' in values:
if values['start_date'] == 'today':
values['start_date'] = datetime.now()
elif values['start_date'] == 'yesterday':
values['start_date'] = datetime.now() - timedelta(1)
else:
values['start_date'] = dt.datetime.strptime(values['start_date'], '%Y-%m-%d %H:%M:%S')
for values in params.values():
if 'end_date' in values:
if values['end_date'] == 'today':
values['end_date'] = datetime.now()
elif values['end_date'] == 'yesterday':
values['end_date'] = datetime.now() - timedelta(1)
else:
values['end_date'] = dt.datetime.strptime(values['end_date'], '%Y-%m-%d %H:%M:%S')
但是代码确实很丑,并且违反了DRY。是否有更好的方法来遍历嵌套dic并更改某些键的值?
答案 0 :(得分:1)
这有点紧凑:
for values in params.values():
for k in ('since','until','start_date','end_date'):
if k in values:
if values[k] == 'today':
values[k] = datetime.now()
elif values[k] == 'yesterday':
values[k] = datetime.now() - timedelta(1)
else:
values[k] = dt.datetime.strptime(values[k], '%Y-%m-%d %H:%M:%S')
答案 1 :(得分:1)
我不是Python开发人员,但是我可以看到您在同一数据上循环了4次,而您只应该执行一次:
def formatDate(value, default):
if value == 'today':
date = datetime.now()
elif value == 'yesterday':
date = datetime.now() - timedelta(1)
else:
date = default
return date
def your_function():
for values in params.values():
if 'since' in values:
values['since'] = formatDate(values['since'], dt.datetime.strptime(values['since'], '%Y-%m-%d %H:%M:%S'))
if 'until' in values:
values['until'] = formatDate(values['until'], dt.datetime.strptime(y['until'], '%Y-%m-%d %H:%M:%S'))
if 'start_date' in values:
values['start_date'] = formatDate(values['start_date'], dt.datetime.strptime(values['start_date'], '%Y-%m-%d %H:%M:%S'))
if 'end_date' in values:
values['end_date'] = formatDate(values['end_date'], dt.datetime.strptime(values['end_date'], '%Y-%m-%d %H:%M:%S'))
代码未经测试,但是我将通用逻辑提取到一个函数中,并且只有一个foreach循环。
答案 2 :(得分:1)
加载json之后,您无需使用嵌套的dict进行迭代,而是需要使用json.loads()的object_hook方法对导入时的日期进行反序列化(我假设您正在使用内置的json库来解析json)。
已经回答了,请看一下这个线程: How to convert to a Python datetime object with JSON.loads?
答案 3 :(得分:1)
考虑嵌套字典理解和字典映射函数以进行时间转换:
def time_conversion(arg):
switcher = {
'today': datetime.now(),
'yesterday': datetime.now() - timedelta(1)
}
output = (datetime.strptime(arg, '%Y-%m-%d %H:%M:%S')
if arg not in switcher.keys() else switcher.get(arg))
return output
new_params = {outer_k:{inner_k: time_conversion(inner_v)
if inner_k in ('since', 'until', 'date_preset') else inner_v
for inner_k, inner_v in outer_v.items()}
for outer_k, outer_v in params.items()}