基于将日期列表与字典中的日期进行比较,在Python中构建值的字典

时间:2014-05-21 18:34:56

标签: python dictionary

我有一个我建立的日期列表(最近30天),然后我还有从我的数据库返回的数据,其中包含日期和这些日期的计数(我将在此描述后发布一些示例数据) )。我想从这两个字典中构建一个字典,如果没有从数据库返回日期,它将放入占位符值。

这是我的日期列表 - 它也是这样的:http://screencast.com/t/VeB37A3k7KO

temp_dates = [
    datetime.date(2014, 4, 21),
    datetime.date(2014, 4, 22),
    datetime.date(2014, 4, 23),
    datetime.date(2014, 4, 24),
    ....
    datetime.date(2014, 5, 18),
    datetime.date(2014, 5, 19),
    datetime.date(2014, 5, 20),
    datetime.date(2014, 5, 21)
]

从我的数据库返回的数据是字典列表。它看起来像这样:

temp_data = [
    {u'daily_count': 3, u'total_count': 684, u'm_date': datetime.date(2014, 4, 21)},
    {u'daily_count': 2, u'total_count': 686, u'm_date': datetime.date(2014, 4, 22)},
    {u'daily_count': 32, u'total_count': 718, u'm_date': datetime.date(2014, 4, 23)},
    {u'daily_count': 1, u'total_count': 719, u'm_date': datetime.date(2014, 4, 25)},
    {u'daily_count': 1, u'total_count': 720, u'm_date': datetime.date(2014, 4, 26)},
    {u'daily_count': 17, u'total_count': 737, u'm_date': datetime.date(2014, 4, 29)},
    {u'daily_count': 1, u'total_count': 740, u'm_date': datetime.date(2014, 5, 2)},
    {u'daily_count': 1, u'total_count': 741, u'm_date': datetime.date(2014, 5, 4)},
    {u'daily_count': 1, u'total_count': 744, u'm_date': datetime.date(2014, 5, 6)},
    {u'daily_count': 2, u'total_count': 746, u'm_date': datetime.date(2014, 5, 8)}
    ...... etc.
]

我想构建一个循环遍历temp_dates中日期的字典,如果temp_data中的日期匹配,则将日期作为新的字典键,将total_count作为值。如果有一个不匹配的日期,则输入之前输入的值。

这就是我做的事。

sql_info = {}
placeholder = 0

for i in temp_dates:
    for j in temp_data:
        if i == j['m_date']:
            sql_info[i] = j['total_count']
            placeholder = j['total_count']
            break
        else:
            sql_info[i] = placeholder

这不起作用。它只是在第一次通过循环放入第一个值后,每次都放入占位符。 684 http://screencast.com/t/BWUfFvYL

如何解决此问题?


我的工作尝试

    for i in temp_dates:
        dd = i.strftime('%m-%d-%Y')
        sql_info[dd] = {}
        for j in temp_data:
            if i == j['m_date']:
                sql_info[dd]['total_count'] = j['total_count']
                placeholder = j['total_count']
                break
            else:
                if placeholder == 0:
                    placeholder = j['total_count'] - j['daily_count']
                sql_info[dd]['total_count'] = placeholder

如果第一次没有日期,请计算total_count - daily_count以获取该日期之前的计数。预期的输出是这样的:http://screencast.com/t/0nCGTnAwJq -----如果那里没有日期,那么我将它添加到字典中并输入适当的值(它是每个日期的五个不同值放入)。

3 个答案:

答案 0 :(得分:2)

不完全确定我是否得到你想要的东西,但这会记录所有占位符,并使用占位符[-2]添加第二个最后总计数值附加前一个值。

如果您不想在另一个日期匹配之前更改该值,则可以使用计数器跟踪并使用占位符[-count]

之类的内容
sql_info = {}
placeholder = []
for i,j in zip(temp_data,temp_dates):
    placeholder.append(i['total_count'])
    if i['m_date'] in temp_dates:
        sql_info[j] = i['total_count']
    else:
        sql_info[j] = placeholder[-2]

这使用strftime来匹配您编辑的答案。

sql_info = {}
placeholder = []
count = 1
for i,j in zip(temp_data,temp_dates):
    dd = j.strftime('%m-%d-%Y')
    placeholder.append(i['total_count'])
    if i['m_date'] in temp_dates:
        sql_info[dd] = i['total_count']
    else:
        count += 1
        sql_info[dd] = placeholder[-count]
print sql_info

答案 1 :(得分:1)

这种情况正在发生,因为一旦函数第一次找不到i==j['m_date'],就会调用“break”。

在此示例中,因为i和j中的前两个值彼此匹配,所以它将设置占位符684,然后将其设置为sql_info[i]以用于循环的其余部分。

答案 2 :(得分:0)

最好的选择可能是将您的查询更改为仅选择m_date在列表中的行。

但我认为

import bisect
def get_date_count_dict(list_of_dates,dates_count_dict):
    dates_items = sorted(dates_count_dict.items(),key=lambda item:item[0])
    sorted_dates,sorted_counts = zip(*dates_items)
    return dict([(a_date,sorted_counts[bisect.bisect(sorted_dates,a_date)])for a_date in list_of_dates])

new_data = dict([(d['m_date'],d['total_count']) for d in temp_data])
final_data = get_date_count_dict(temp_dates,new_data)

应该有用。