You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyYAML 3.12在不同操作系统下键遍历顺序差异原因咨询

为什么PyYAML 3.12在不同Python版本下遍历键的顺序不同?

这个差异的核心原因完全在于你使用的Python版本对字典有序性的实现不同,和PyYAML 3.12本身关系不大——PyYAML在这里只是直接复用了Python内置字典的行为。

让我具体拆解:

  • Linux上的Python 3.4.8:这个版本的Python字典基于传统哈希表实现,不保证保留插入顺序。当PyYAML加载YAML映射时,它会把键值对存入普通字典,遍历的时候Python会按哈希值排序后返回键,所以你看到的是字母序的function_a→function_b→function_c→function_d。
  • Windows上的Python 3.6.5:虽然Python官方直到3.7才把「字典保留插入顺序」列为语言规范,但CPython 3.6的字典实现已经偷偷改成了能保留插入顺序的结构(这是CPython的一个优化特性,当时还不是标准)。所以PyYAML加载YAML后,字典会保留YAML文件里键的原始顺序,也就是你看到的function_a→function_c→function_d→function_b。

如果你需要在所有Python版本下都保证遍历顺序和YAML文件一致,有个简单的解决办法:让PyYAML把映射加载为OrderedDict而不是普通字典。你可以自定义一个构造器来实现:

from collections import OrderedDict
import yaml

def ordered_yaml_load(stream):
    # 自定义构造器,把YAML映射转为OrderedDict
    def construct_ordered_mapping(loader, node):
        loader.flatten_mapping(node)
        return OrderedDict(loader.construct_pairs(node))
    yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_ordered_mapping)
    return yaml.load(stream)

# 使用这个函数加载YAML
with open('myyamlfile.yml') as fp:
    conf = ordered_yaml_load(fp)

# 此时遍历conf['functions'],顺序会和YAML文件里完全一致
for function in conf['functions']:
    print(function)

另外提一句:PyYAML 5.1+版本开始支持直接通过yaml.load的Loader参数指定yaml.FullLoader,并且可以结合typ='ordered'来直接加载为有序字典,不过你用的是3.12版本,所以上面的自定义构造器方法更适合你。

内容的提问来源于stack exchange,提问作者brillenheini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:57:27