dict.setdefault() 当值已经存在时使用
dict.setdefault() is used when value already exists
我正在尝试向现有字典添加新键,将前一个键的值设置为默认值。
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
是如何工作的,也许这个问题有替代解决方案。
您误解了错误。 KeyError
表示您尝试在字典中查找键,但该键不存在。在这种情况下,它看起来像 profile[start+datetime.timedelta(day-1)]
给你 KeyError
并且与 setdefault
方法调用无关。
考虑如何在没有 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
的唯一用途是使用密钥 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}
的等价物。
我正在尝试向现有字典添加新键,将前一个键的值设置为默认值。
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
是如何工作的,也许这个问题有替代解决方案。
您误解了错误。 KeyError
表示您尝试在字典中查找键,但该键不存在。在这种情况下,它看起来像 profile[start+datetime.timedelta(day-1)]
给你 KeyError
并且与 setdefault
方法调用无关。
考虑如何在没有 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
的唯一用途是使用密钥 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}
的等价物。