Is the order of a Python dictionary guaranteed over iterations?

依然范特西╮ 提交于 2019-11-29 01:00:38

Python 3.1 has a collections.OrderedDict class that can be used for this purpose. It's very efficient, too: "Big-O running times for all methods are the same as for regular dictionaries."

The code for OrderedDict itself is compatible with Python 2.x, though some inherited methods (from the _abcoll module) do use Python 3-only features. However, they can be modified to 2.x code with minimal effort.

truppo

Yes, the same order is guaranteed if it is not modified.

See the docs here.

Edit:

Regarding if changing the value (but not adding/removing a key) will affect the order, this is what the comments in the C-source says:

/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
 * dictionary if it's merely replacing the value for an existing key.
 * This means that it's safe to loop over a dictionary with PyDict_Next()
 * and occasionally replace a value -- but you can't insert new keys or
 * remove them.
 */

It seems that its not an implementation detail, but a requirement of the language.

Gabriel Hurley

Provided no modifications are made to the dictionary, the answer is yes. See the docs here.

However, dictionaries are unordered by nature in Python. In general, it's not the best practice to rely on dictionaries for sensitive sorted data.

An example of an a more robust solution would be Django's SortedDict data structure.

If you want the order to be consistent, I would do something to force a particular order. Although you might be able to convince yourself that the order is guaranteed, and you might be right, it seems fragile to me, and it will be mysterious to other developers.

For example, you emphasize always in your question. Is it important that it be the same order in Python 2.5 and 2.6? 2.6 and 3.1? CPython and Jython? I wouldn't count on those.

I also would recommend not relying on the fact the dictionaries order is non-random.

If you want a built in solution to sorting you dictionary read http://www.python.org/dev/peps/pep-0265/

Here is the most relevant material:

This PEP is rejected because the need for it has been largely fulfilled by Py2.4's sorted() builtin function:

    >>> sorted(d.iteritems(), key=itemgetter(1), reverse=True)
    [('b', 23), ('d', 17), ('c', 5), ('a', 2), ('e', 1)]

or for just the keys:

    >>> sorted(d, key=d.__getitem__, reverse=True)
    ['b', 'd', 'c', 'a', 'e']

Also, Python 2.5's heapq.nlargest() function addresses the common use
case of finding only a few of the highest valued items:

    >>> nlargest(2, d.iteritems(), itemgetter(1))
    [('b', 23), ('d', 17)]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!