Python 字典:keys() 和 values() 的顺序总是一样的吗?
- 2024-12-31 08:37:00
- admin 原创
- 125
问题描述:
看起来字典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
如果不改变 callingkeys()
和 calling之间的字典values()
,那么假设上述 for 循环将始终打印 True 是否错误?我找不到任何文档来证实这一点。
解决方案 1:
发现了这个:
如果调用
items()
、keys()
、values()
、
iteritems()
、iterkeys()
和 且
itervalues()
中间不修改字典,则列表将直接对应。
关于2.x 文档和3.x 文档。
解决方案 2:
是的,您观察到的确实是一个有保证的属性 -- keys()
,values()
并且items()
如果字典没有改变则按一致顺序返回列表。 iterkeys()
&c 也按照与相应列表相同的顺序进行迭代。
解决方案 3:
是的,在 python 2.x 中保证:
如果对键、值和项目视图进行迭代,且中间没有对字典进行修改,则项目的顺序将直接对应。
解决方案 4:
是的。从 CPython 3.6 开始,字典按您插入项目的顺序返回项目。
忽略“这是实现细节”这一部分。此行为在 CPython 3.6 中得到保证,并且从 Python 3.7 开始,所有其他 Python 实现都需要此行为。
解决方案 5:
很好的文档参考。以下是无论文档/实现如何都可以保证顺序的方法:
k, v = zip(*d.iteritems())
解决方案 6:
根据http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects,字典的 keys()、values() 和 items() 方法将返回顺序对应的迭代器。但是,我无法找到有关 python 2.x 官方文档的参考。
据我所知,答案是肯定的,但仅限于 python 3.0+
解决方案 7:
不管怎样,我编写的一些大量使用的生产代码都是基于这个假设的,我从来没有遇到过问题。但我知道这并不代表事实 :-)
如果您不想冒险,我建议您使用 iteritems()。
for key, value in myDictionary.iteritems():
print key, value
解决方案 8:
我同意其他人的观点,即在 python 3.6+ 中,如果不受用户影响,它应该保持不变。
来自我几天前的代码的一个例子:
ips = { '001' : '199.250.178.14', '002' : '199.18.2.89', '003' : '109.251.63.21' }
def run(self):
for x, y in self.ips.items():
try:
subprocess.check_call(
['ping', '-n', '1', y],
stdout=DEVNULL, # suppress output
stderr=DEVNULL
)
except subprocess.CalledProcessError:
nextServer = ('HUB ' + x + ' is OFFLINE ' + " IP: " + y)
并且输出始终是相同的顺序,与我输入的顺序完全一致,即只有离线服务器才会按顺序显示:HUB 003 是离线 IP:109.251.63.21,因为前两个是可访问的
希望这能解决
解决方案 9:
我对这些答案并不满意,因为我想确保即使使用不同的字典,导出的值也具有相同的顺序。
在这里您预先指定键的顺序,即使字典发生变化或您使用不同的字典,返回的值也将始终具有相同的顺序。
keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]