0

我正在尝试向现有字典添加新键,将前一个键的值设置为默认值。

def check_data(end, start, profile):
    print(profile)

    for day in range((end-start).days+1):
        profile.setdefault(start+datetime.timedelta(day),
           {'expediture':0, 'top-up':0,
           'budget':profile[start+datetime.timedelta(day-1)]['budget'] })

start  = datetime.date(2019,2,1)
end    = datetime.date(2019,2,17)
check_data(end, start, month_data)

输出print(profile)

    {datetime.date(2019, 2, 1): {'expediture': 0, 'top-up': 0, 'budget': 100.0}}

 ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    <ipython-input-4-e44462627692> in <module>
    ----> 1 check_data(end, start, month_data)

    <ipython-input-2-90b936150b04> in check_data(end, start, profile)
         20         profile.setdefault(start+datetime.timedelta(day),
         21                                     {'expediture':0, 'top-up':0,
    ---> 22
       'budget':profile[start+datetime.timedelta(day-1)]['budget'] })
        23
        24 def add_money(profile, topup, date=datetime.date.today()):

       KeyError: datetime.date(2019, 1, 31)

我不明白为什么要setdefault()尝试将默认值设置为 datetime.date(2019, 2, 1)如果该值已经存在。

我可以解决这个问题,if但我想了解它是如何setdefault工作的,也许这个问题有替代解决方案。

4

2 回答 2

1

您误解了错误。AKeyError表示您试图在字典中查找一个键,但该键不存在。在这种情况下,它看起来像是profile[start+datetime.timedelta(day-1)]给你的并且与方法调用KeyError无关。setdefault

于 2019-02-15T17:47:56.973 回答
0

考虑如何在没有 setdefault(以及一些小的重构以提高可读性)的情况下编写此代码:

def check_data(end, start, profile):
    print(profile)

    for day in range((end-start).days+1):
        yesterday = start + datetime.timedelta(day - 1)
        today = start + datetime.timedelta(day)
        profile[today] = {
            'expenditure': 0,
            'top-up': 0,
            'budget': profile[yesterday]['budget']
        }

start  = datetime.date(2019,2,1)
end    = datetime.date(2019,2,17)
check_data(end, start, month_data)

在循环的第一次迭代中,您需要 的值profile[datetime(2019,1,31)]才能设置 的值profile[datetime(2019,2,1)],但从未设置过该值。

这里唯一的用途setdefault是 key yesterday,假设您可以从一些通用配置文件开始。为简单起见,我假设它budget也是一个整数。

def check_data(end, start, profile):
    print(profile)

    for day in range((end-start).days+1):
        yesterday = start + datetime.timedelta(day - 1)
        today = start + datetime.timedelta(day)
        profile[today] = {
            'expenditure': 0,
            'top-up': 0,
            'budget': profile.setdefault(yesterday, {'budget': 0})['budget']
        }

现在,如果profile[yesterday]不存在,将在返回该值之前setdefault执行等效的。profile[yesterday] = {'budget': 0}

于 2019-02-15T18:23:13.343 回答