如何根据键对defaultdict排序?
我正在根据时间戳把一组对象归类在一起:
object_list = [
{
timestamp: datetime.strptime("01/01/2014", "%d/%m/%y"),
},
{
timestamp: datetime.strptime("12/05/2014", "%d/%m/%y"),
},
{
timestamp: datetime.strptime("03/01/2014", "%d/%m/%y"),
},
{
timestamp: datetime.strptime("01/01/2014", "%d/%m/%y"),
}]
date_grouped_objects = defaultdict(list)
for obj in object_list:
date_grouped_objects[obj.timestamp].append(obj)
这样做的结果正是我想要的,得到了一组根据时间戳属性归类的对象。
问题是:我现在想根据这些时间戳对 date_grouped_objects 进行排序,但不太清楚如何使用 sorted 来实现这个目标?我希望最新的日期组排在最后。
所以我想要的是:
[
["01/01/2014"] = [...],
["03/01/2014"] = [...],
["12/05/2014"] = [...],
]
其中这些键实际上是日期对象,而不是字符串。
3 个回答
0
使用内置的排序方法。这个方法可以同时对值和键进行排序。你还可以利用关键字和反向参数来进行更复杂的排序。
8
像大多数地图(Map)实现一样,defaultdict
是没有顺序的1,所以它本身不能被“排序”。
不过,里面的items()
配对是可以排序的,排序后的结果是一个序列(列表),而不是一个字典(dict)。这个包含元组的可迭代对象,排序时会把排序的关键字放在前面,因为元组的默认排序是从左到右一对一地进行的。
d = {'c': 1, 'a': 2, 'b': 3}
s = sorted(d.items())
# s -> [('a', 2), ('b', 3), ('c', 1)]
对于更复杂的情况,可以使用自定义的比较函数或者关键字选择函数来进行排序;这两种方法的输出结果是一样的。
s = sorted(d.items(), lambda a, b: a[0] >= b[0])
s = sorted(d.items(), key = lambda i: i[0])
1可以使用OrderedDict来保持插入顺序,一旦键被排序。
OrderedDict 是一种字典,它记住了键最初插入的顺序。
不过,我不建议在算法中依赖这种特殊的保证。
import collections
od = collections.OrderedDict(s)
5
你可以使用我在另一个回答中提到的OrderedDefaultdict
类,来做类似下面的事情:
from datetime import datetime
from ordereddefaultdict import OrderedDefaultdict
object_list = [{'timestamp': datetime.strptime("01/01/2014", "%d/%m/%Y")},
{'timestamp': datetime.strptime("12/05/2014", "%d/%m/%Y")},
{'timestamp': datetime.strptime("03/01/2014", "%d/%m/%Y")},
{'timestamp': datetime.strptime("01/01/2014", "%d/%m/%Y")},]
date_grouped_objects = OrderedDefaultdict(list)
for obj in sorted(object_list):
key = obj['timestamp'].strftime("%d/%m/%Y") # convert datetime to string
date_grouped_objects[key].append(obj)
for key, value in date_grouped_objects.iteritems():
print '[{!r}] = {}'.format(key, value)
输出结果:
['01/01/2014'] = [{'timestamp': datetime.datetime(2014, 1, 1, 0, 0)},
{'timestamp': datetime.datetime(2014, 1, 1, 0, 0)}]
['03/01/2014'] = [{'timestamp': datetime.datetime(2014, 1, 3, 0, 0)}]
['12/05/2014'] = [{'timestamp': datetime.datetime(2014, 5, 12, 0, 0)}]