为什么在 2005 年生成假期列表会破坏此功能?
why do does generating a list of holidays in the year 2005 blow up this function?
我正在使用 datetime
、holidays
和 dateutil
编写 Python 脚本来确定 YYYY-MM-DD
格式的给定日期是否为交易假期.我正在使用生成器表达式从 holidays
库
提供的默认假期列表中删除市场未关闭的假期
import datetime, holidays
import dateutil.easter as easter
def to_date(date_string):
return datetime.datetime.strptime(date_string,'%Y-%m-%d').date()
def is_trading_holiday(date):
us_holidays = holidays.UnitedStates(years=date.year)
# generate list without columbus day and veterans day since markets are open on those days
trading_holidays = [ "Columbus Day", "Columbus Day (Observed)", "Veterans Day", "Veterans Day (Observed)"]
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
# add good friday to list since markets are closed on good friday
custom_holidays.append(easter.easter(year=date.year) - datetime.timedelta(days=2))
return date in custom_holidays
if __name__=="__main__":
first_date = to_date('2020-01-03')
second_date = to_date('2015-11-26') # Thanksgiving
third_date = to_date('2005-01-01') # New Years
fourth_date = to_date('2005-01-07')
print(is_trading_holiday(first_date))
print(is_trading_holiday(second_date))
print(is_trading_holiday(third_date))
print(is_trading_holiday(fourth_date))
我已经针对各种日期对此进行了测试,它似乎在所有情况下都有效,但只有一种情况除外。当我使用 2005 年的日期时,这个函数会崩溃并告诉我,
Traceback (most recent call last):
File "./test.py", line 26, in <module>
print(is_trading_holiday(third_date))
File "./test.py", line 11, in is_trading_holiday
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
File "./test.py", line 11, in <listcomp>
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
RuntimeError: dictionary changed size during iteration
我不知道 2005 年有什么特别之处导致此功能崩溃,或者即使这一年是导致此问题的原因(我已经针对可追溯到 70 年代的日期进行了测试,并且它有效)。我没有修改我在生成器表达式中迭代的字典(否则,我不认为是?),所以我不确定这个错误试图告诉我什么。
有人知道这是怎么回事吗?我是否漏掉了一些明显的东西?
在美国 class 似乎有一个错误(或特殊情况)会为 2005 年生成 datetime.date(2004, 12, 31): "New Year's Day (Observed)"
。这会导致 if us_holidays[date]
在您的列表理解中引用不同的年份(尚未加载)并对您正在遍历的字典进行更改。
您可以通过遍历项目而不是使用键重新访问字典来解决该问题:
... for date,name in us_holidays.items() if name not in trading_holidays]
或者,您可以只转换为列表,这样迭代就不会 运行 通过实际字典:
... for date in list(us_holidays) if us_holidays[date] not in trading_holidays]
我正在使用 datetime
、holidays
和 dateutil
编写 Python 脚本来确定 YYYY-MM-DD
格式的给定日期是否为交易假期.我正在使用生成器表达式从 holidays
库
import datetime, holidays
import dateutil.easter as easter
def to_date(date_string):
return datetime.datetime.strptime(date_string,'%Y-%m-%d').date()
def is_trading_holiday(date):
us_holidays = holidays.UnitedStates(years=date.year)
# generate list without columbus day and veterans day since markets are open on those days
trading_holidays = [ "Columbus Day", "Columbus Day (Observed)", "Veterans Day", "Veterans Day (Observed)"]
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
# add good friday to list since markets are closed on good friday
custom_holidays.append(easter.easter(year=date.year) - datetime.timedelta(days=2))
return date in custom_holidays
if __name__=="__main__":
first_date = to_date('2020-01-03')
second_date = to_date('2015-11-26') # Thanksgiving
third_date = to_date('2005-01-01') # New Years
fourth_date = to_date('2005-01-07')
print(is_trading_holiday(first_date))
print(is_trading_holiday(second_date))
print(is_trading_holiday(third_date))
print(is_trading_holiday(fourth_date))
我已经针对各种日期对此进行了测试,它似乎在所有情况下都有效,但只有一种情况除外。当我使用 2005 年的日期时,这个函数会崩溃并告诉我,
Traceback (most recent call last):
File "./test.py", line 26, in <module>
print(is_trading_holiday(third_date))
File "./test.py", line 11, in is_trading_holiday
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
File "./test.py", line 11, in <listcomp>
custom_holidays = [ date for date in us_holidays if us_holidays[date] not in trading_holidays ]
RuntimeError: dictionary changed size during iteration
我不知道 2005 年有什么特别之处导致此功能崩溃,或者即使这一年是导致此问题的原因(我已经针对可追溯到 70 年代的日期进行了测试,并且它有效)。我没有修改我在生成器表达式中迭代的字典(否则,我不认为是?),所以我不确定这个错误试图告诉我什么。
有人知道这是怎么回事吗?我是否漏掉了一些明显的东西?
在美国 class 似乎有一个错误(或特殊情况)会为 2005 年生成 datetime.date(2004, 12, 31): "New Year's Day (Observed)"
。这会导致 if us_holidays[date]
在您的列表理解中引用不同的年份(尚未加载)并对您正在遍历的字典进行更改。
您可以通过遍历项目而不是使用键重新访问字典来解决该问题:
... for date,name in us_holidays.items() if name not in trading_holidays]
或者,您可以只转换为列表,这样迭代就不会 运行 通过实际字典:
... for date in list(us_holidays) if us_holidays[date] not in trading_holidays]