我有以下字典:
history = {
"2008-11-17": 41,
"2010-05-28": 82,
"2008-11-14": 47,
"2008-11-13": 60,
"2008-11-12": 56,
"2008-11-11": 55,
"2008-11-10": 98,
"2008-11-19": 94,
"2008-11-18": 94,
"2004-05-27": 82,
"2004-05-26": 45,
"2004-05-25": 70,
# there's more ...
}
如何定义生成器函数get_records(dict_history, str_from_date, str_to_date)
以生成date: record
条目?
我知道如何将datetime
个对象转换为我想要的任何字符串格式。然而,我在这个障碍中的主要痛点是:
dict
未订购。dict
键是字符串。到目前为止,这是我能想到的:
from datetime import datetime, timedelta
def get_records(history, start_date, end_date):
fmt = "%Y-%m-%d"
dt = timedelta(days=1)
present_date = datetime.strptime(start_date, fmt)
end_date = datetime.strptime(end_date, fmt)
while present_date <= end_date:
present_string = present_date.strftime(fmt)
try:
yield (present_string, history[present_string])
except KeyError:
pass
present_date += dt
有更有效的方法吗?
更新(2011年8月2日)
我在ActiveState找到了一个SortedCollection
课,也是由Raymond Hettinger创建的。
答案 0 :(得分:5)
我只是迭代字典并返回匹配的项目:
def get_records(history, start_date, end_date):
for date, entry in history.iteritems():
if start_date <= date <= end_date:
yield date, entry
请注意,您的特定日期格式允许与<
和>
进行直接字符串比较,而无需先转换为datetime
实例。
另请注意,给定的函数将以无特定顺序返回匹配项。
答案 1 :(得分:0)
怎么样:
def get_records(history, start_date, end_date, format = "%Y-%m-%d"):
present_date = datetime.strptime(start_date, format)
end_date = datetime.strptime(end_date, format)
return [(key, value) for key, value in history.items() if present_date <= datetime.strptime(history[key], format) <= end_date]
答案 2 :(得分:0)
history = { "2008-11-17": 41,
"2010-05-28": 82,
"2008-11-14": 47,
"2008-11-13": 60,
"2008-11-12": 56,
"2008-11-11": 55,
"2008-11-10": 98,
"2008-11-19": 94,
"2008-11-18": 94,
"2004-05-27": 82,
"2004-05-26": 45,
"2004-05-25": 70 }
def get_records(dict_history, str_from_date, str_to_date):
for k,v in sorted(dict_history.items()):
if k>str_to_date:
break
if k>=str_from_date:
yield (k,v)
print history.items()
print
print list( get_records(history, '2005-05-21', '2008-12-25'))
日期是字符串'yyyy-mm-jj'
按字典顺序排序这些字符串会产生与根据它们所代表的日期对它们进行排序相同的结果。
sorted(dict_history.items())是一个元组列表。 Python根据元组的第一个元素对此列表进行排序 字典中的每个键都是唯一的,这种排序没有歧义。
回答您的表现问题:
history = { "2008-11-17": 41,
"2010-05-28": 82,
"2008-11-14": 47,
"2008-11-13": 60,
"2008-11-12": 56,
"2008-11-11": 55,
"2008-11-11": 02,
"2008-11-10": 98,
"2008-11-19": 94,
"2008-11-18": 94,
"2004-05-27": 82,
"2004-05-26": 45,
"2004-05-25": 70 }
import bisect
def get_records(dict_history, str_from_date, str_to_date):
sorted_keys = sorted(dict_history.iterkeys())
start = bisect.bisect_left(sorted_keys,str_from_date)
end = bisect.bisect_right(sorted_keys,str_to_date)
for date in sorted(dict_history.iteritems())[start:end]:
yield date
print history.items()
print
print list( get_records(history, '2005-05-21', '2008-12-25'))
答案 3 :(得分:0)
def get_records(history, str_from_date, str_to_date)
return sorted((k,v) for k,v in history.iteritems() if str_from_date<=k<=str_to_date)
答案 4 :(得分:0)
这只会通过一行日期,而不是首先对列表进行排序。
from datetime import datetime, timedelta
def get_records(history, start_date, end_date):
fmt = "%Y-%m-%d"
start_date = datetime.strptime(start_date, fmt)
end_date = datetime.strptime(end_date, fmt)
dt = history.iteritems()
dt = sorted(dt, key= lambda date: datetime.strptime(date[0], fmt))
for date in dt:
if datetime.strptime(date[0],fmt) > end_date:
break
elif datetime.strptime(date[0],fmt) >= start_date:
yield(date[0], history[date[0]])
else:
pass