【问题标题】:Python: Element order in dictionaryPython:字典中的元素顺序
【发布时间】:2011-08-13 03:02:57
【问题描述】:

这是我的 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!

有没有办法保持原始元素顺序,所以帖子将按added in posts_to_return 排序?

谢谢!

编辑: Python 2.6,Django 1.3

【问题讨论】:

    标签: python django


    【解决方案1】:

    使用 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()
    

    【讨论】:

    • 谢谢! arie 更快,但由于这个例子,我接受了你的回答。
    【解决方案2】:

    python(和大多数语言)中的字典没有顺序。您应该改用collections.OrderedDict。这将在添加项目时保留项目的顺序。如果添加顺序不是您想要保留的顺序,您也可以查看 sorted() 内置函数。

    【讨论】:

    • Django 的意思是,我必须坚持使用 python 2.x
    • @Silver Light:你看到OrderedDict in py2.4 的“另见”位了吗?
    • @Silver Light:OrderedDict 是 Python 2.7x 标准库的一部分
    【解决方案3】:

    还值得注意的是,您可以使用 Python 的许多字典实现之一,以按排序顺序维护键。如果您打算对已排序的字典进行任何插入,这一点至关重要。考虑sortedcontainers module,它是纯 Python 和 fast-as-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()]
    

    还有一个performance comparison 可以将几个流行的选项相互进行基准测试。

    【讨论】:

      【解决方案4】:

      当您使用 Django 时,您可以使用 SortedDict (docs)

      【讨论】:

        【解决方案5】:

        因为还没有人注意到它,所以我会简单地指出 OrderedDict 文档表明 this recipe 是等效的,并且适用于 Python 2.4 及更高版本。所以至少你不必自己动手。

        【讨论】:

          【解决方案6】:

          您需要一个有序字典,据我所知,它在 Python3.3 中可用。因此,您可能必须“手动”订购您的结果。根据您的操作(您没有显示),可能只重用原始帖子列表。但在不知道操作的情况下,我只能猜测。

          【讨论】:

            【解决方案7】:

            您可以使用OrderedDict 代替字典。

            from collections import OrderedDict
            ...
            post_list = OrderedDict([(obj.id, obj) for obj in posts])
            

            【讨论】:

              猜你喜欢
              • 2011-04-29
              • 2020-06-30
              • 1970-01-01
              • 2022-12-24
              • 1970-01-01
              • 2012-05-28
              • 2022-11-04
              • 2020-11-02
              • 1970-01-01
              相关资源
              最近更新 更多