Python:字典中的元素顺序

3 投票
7 回答
2599 浏览
提问于 2025-04-16 16:26

这是我的Django代码,但它的表现和我预期的不太一样:

posts = Post.objects.all().order_by('-added')[:20] # ordered by 'added'
post_list = dict([(obj.id, obj) for obj in posts])

# ... some operations with dictionary elements go here ...

posts_to_return = [post for post_id, post in post_list.items()] # order by 'id' now!

有没有办法保持原来的元素顺序,这样在posts_to_return中,帖子就可以按照added的顺序排列呢?

谢谢!

编辑:使用的是Python 2.6和Django 1.3

7 个回答

4

值得一提的是,Python有很多字典的实现方式,其中一些可以保持键的顺序是排好序的。如果你打算在这个有序字典里插入数据,这一点非常重要。你可以看看sortedcontainers模块,它是用纯Python写的,速度跟C语言一样快。里面有一个叫SortedDict的实现,正好满足你的需求。

>>> from sortedcontainers import SortedDict
>>> posts = Post.objects.all().order_by('-added')[:20] # ordered by 'added'
>>> post_list = SortedDict([(obj.id, obj) for obj in posts])
>>> # ... some operations with dictionary elements go here ...
>>> # This is now automatically ordered by id:
>>> posts_to_return = [post for post_id, post in post_list.items()]

另外,还有一个性能比较,可以让你看看几个流行的选项之间的表现如何。

6

在Python(以及大多数编程语言)中,字典是没有顺序的。这意味着你添加的内容顺序可能会被打乱。如果你想保持添加的顺序,可以使用collections.OrderedDict。这样的话,添加的项目顺序就会被保留下来。如果你想要的顺序不是添加的顺序,你也可以使用内置的sorted()函数来排序。

6

使用 SortedDict 替代普通的 dict(from django.utils.datastructures import SortedDict

SortedDict 会保持它的顺序,这个顺序保存在 keyOrder 属性里。所以如果你想改变顺序,可以直接操作这个属性,而不需要重新构建一个新的 dict。比如,如果你想把 SortedDict 的顺序反转,只需使用 keyOrder.reverse() 就可以了。

post_list = SortedDict([(obj.id, obj) for obj in posts])
# reversing the post order in-place
post_list.keyOrder.reverse()

撰写回答