Python字典:keys()和values()总是相同的顺序吗?

问题:Python字典:keys()和values()总是相同的顺序吗?

看起来字典的keys()values()方法返回的列表始终是一对一映射(假设在调用这两种方法之间字典没有改变)。

例如:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

如果您没有在调用keys()和调用之间更改字典values(),那么假设上述for循环将始终显示True是否错误?我找不到任何证明文件。

It looks like the lists returned by keys() and values() methods of a dictionary are always a 1-to-1 mapping (assuming the dictionary is not altered between calling the 2 methods).

For example:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

If you do not alter the dictionary between calling keys() and calling values(), is it wrong to assume the above for-loop will always print True? I could not find any documentation confirming this.


回答 0

发现了这一点:

如果items()keys()values()iteritems()iterkeys(),和 itervalues()被称为中间没有修改的字典,列表会直接对应。

2.x文档3.x文档上

Found this:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are called with no intervening modifications to the dictionary, the lists will directly correspond.

On 2.x documentation and 3.x documentation.


回答 1

是的,您观察到的确实是一个有保证的属性-如果未更改dict,则keys(),values()和items()会以一致的顺序返回列表。iterkeys()&c也以与相应列表相同的顺序进行迭代。

Yes, what you observed is indeed a guaranteed property — keys(), values() and items() return lists in congruent order if the dict is not altered. iterkeys() &c also iterate in the same order as the corresponding lists.


回答 2

是的,在python 2.x中可以保证

如果对键,值和项目视图进行了迭代而没有对字典进行任何中间修改,则项目的顺序将直接对应。

Yes it is guaranteed in python 2.x:

If keys, values and items views are iterated over with no intervening modifications to the dictionary, the order of items will directly correspond.


回答 3

是。从CPython 3.6开始,字典按插入顺序返回项目

忽略说这是实现细节的部分。此行为在CPython 3.6中得到保证,并且从Python 3.7开始的所有其他Python实现都需要此行为。

Yes. Starting with CPython 3.6, dictionaries return items in the order you inserted them.

Ignore the part that says this is an implementation detail. This behaviour is guaranteed in CPython 3.6 and is required for all other Python implementations starting with Python 3.7.


回答 4

对文档的良好引用。无论文档/实现如何,都可以通过以下方法保证订单的准确性:

k, v = zip(*d.iteritems())

Good references to the docs. Here’s how you can guarantee the order regardless of the documentation / implementation:

k, v = zip(*d.iteritems())

回答 5

根据http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects,dict的keys(),values()和items()方法将返回其顺序的相应迭代器对应。但是,对于同一件事,我无法找到python 2.x官方文档的引用。

据我所知,答案是肯定的,但仅适用于python 3.0+

According to http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects , the keys(), values() and items() methods of a dict will return corresponding iterators whose orders correspond. However, I am unable to find a reference to the official documentation for python 2.x for the same thing.

So as far as I can tell, the answer is yes, but only in python 3.0+


回答 6

就其价值而言,我编写的一些常用的生产代码都基于此假设,但我从未遇到过任何问题。我知道那不是真的:-)

如果您不想冒险,我会尽可能使用iteritems()。

for key, value in myDictionary.iteritems():
    print key, value

For what it’s worth, some heavy used production code I have written is based on this assumption and I never had a problem with it. I know that doesn’t make it true though :-)

If you don’t want to take the risk I would use iteritems() if you can.

for key, value in myDictionary.iteritems():
    print key, value

回答 7

我对这些答案不满意,因为我想确保即使使用不同的字典,导出的值也具有相同的顺序。

在这里,您可以预先指定键顺序,即使字典更改,返回的值也将始终具有相同的顺序,或者您使用不同的字典。

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]

I wasn’t satisfied with these answers since I wanted to ensure the exported values had the same ordering even when using different dicts.

Here you specify the key order upfront, the returned values will always have the same order even if the dict changes, or you use a different dict.

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]