如何将代码更改为仅使用一个循环。我尝试使用.iteritems(),iterkeys()等......
for user in data:
for item in data[user]:
start = seconds_since_midnight(
data[user][item]['start']
)
end = seconds_since_midnight(
data[user][item]['end']
)
overtime = end - start
if overtime > eight_hours:
if user not in result:
if str(user) not in names.keys():
continue
result[user] = {
'name': names[str(user)]['name'],
'overtime': []
}
result[user]['overtime'].append(overtime - eight_hours)
try:
result[user]['overtime'] = sum(result[user]['overtime'])
except KeyError:
pass
return sorted(
result.items(),
key=lambda result: result[1]['overtime'],
reverse=True
)
它创建这样的结构: data = { '用户身份': { datetime.date(2013,10,1):{ 'start':datetime.time(9,0,0), 'end':datetime.time(17,30,0), }, datetime.date(2013,10,2):{ 'start':datetime.time(8,30,0), 'end':datetime.time(16,45,0), }, } }
答案 0 :(得分:2)
首先要注意的是我们可以假设每个用户只在data
中出现一次,因为它是一个字典。
解决方案1
现在介绍这两个功能:
def overtime(item):
start = seconds_since_midnight(item['start'])
end = seconds_since_midnight(item['end'])
return end - start
def comp_hours(name, items):
return {'name': name,
'overtime': sum(overtime(item) - 8 for item in items if overtime(item) > 8)}
现在做这个字典理解:
result = {u: comp_hours(names[str(u)]['name'], i) for u, i in data.items() if str(u) in names}
result_filtered = {k: v for k, v in result.items() if v > 0}
你必须自己进行排序。
解决方案2
我们修改了第一个解决方案。
介绍功能
def total_overtime(items):
return sum(overtime(item) - 8 for item in items if overtime(item) > 8)
def comp_hours_new(user, items):
return {'name': names[str(user)]['name'], 'overtime': total_overtime(items)}
def condition(user, items):
return str(user) in names and total_overtime(items) > 0
然后这样做
{u: comp_hours_new(u, i) for u, i in data.items() if condition(u, i)}
使用函数式编程,您不必计算total_overtime
和overtime
2X。
毕竟这个是这种模式的经典案例
{k: f(k, v) for k, v in your_dict.items() if condition(k, v)}
解决方案3
为了克服缓慢的CPU时间,我们稍微修改了我们的解决方案,并将使用生成器。 介绍功能
def condition_new(user, total_overtime_):
return str(user) in names and total_overtime_ > 0
def comp_hours_new_new(user, total_overtime_):
return {'name': names[str(user)]['name'], 'overtime': total_overtime_}
现在做
I = ((u, total_overtime(i)) for u, i in data.items())
{u: comp_hours_new_new(u, ttl_over) for u, ttl_over in I if condition_new(u, ttl_over)}