Python-更好地循环多维词典的方法



我如何更改代码只使用一个循环。我尝试使用.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
)

它创建这样的结构: 数据= { '用户身份': { 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(, },, } }

首先要说的是,我们可以假设每个用户在 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_overtimeovertime 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)}

最新更新