如何在Python中创建有序字典(OrderedDict)?

45

我尝试维护Python字典的顺序,因为原生的dict没有任何顺序。SE中的许多答案建议使用OrderedDict


from collections import OrderedDict

domain1 = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  }

domain2 = OrderedDict({ "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  })

print domain1
print " "    
for key,value in domain1.iteritems():
    print (key,value)

print " "

print domain2
print ""
for key,value in domain2.iteritems():
    print (key,value)

迭代后,我需要字典保持原来的顺序,并且以原始的方式打印键和值:

{
    "de": "Germany",
    "sk": "Slovakia",
    "hu": "Hungary",
    "us": "United States",
    "no": "Norway"
}

不过,无论我使用哪种方式,都无法保留这个顺序。


2
您首先正在构建一个普通的dict(因为{...}字面量是普通的dict对象),然后将其传递到OrderedDict构造函数中,该构造函数不再看到您的显式顺序。您需要直接将项目添加到OrderedDict中。 - Daniel Pryden
问题已在https://dev59.com/mFgR5IYBdhLWcg3wBZS3中得到解答。 - ilias iliadis
4个回答

73
您需要向其传递一个项目序列或按顺序插入项目,这样它就知道顺序。尝试像这样做:

您需要将一系列项目或按顺序插入项目传递给它- 这是它知道顺序的方式。尝试类似于以下内容:

from collections import OrderedDict

domain = OrderedDict([('de', 'Germany'),
                      ('sk', 'Slovakia'),
                      ('hu', 'Hungary'),
                      ('us', 'United States'),
                      ('no', 'Norway')])

数组是有顺序的,因此OrderedDict将会知道您打算的顺序。


4
一个学究式的注释:一个可迭代对象并不足够(毕竟字典和集合也是可迭代的)。你需要传递给它更接近序列的东西。 - Jared Goguen

4
在使用OrderedDict的情况下,你需要先创建一个中间的普通字典(因此是无序的),然后再将其传递给构造函数。为了保持顺序,你需要在构造函数中传递一个有序的东西(例如元组的列表)或按照你想要的顺序逐个添加键(可能需要使用循环)。

3

虽然回答有点晚,但这里有一个 Python 3.6+ 的单行代码,可以使用 key 对字典进行排序,而不需要使用任何导入模块:

d = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  }
d_sorted = {k: v for k, v in sorted(d.items(), key=lambda x: x[1])}
print(d_sorted)

输出:

{'de': 'Germany', 'hu': 'Hungary', 'no': 'Norway', 'sk': 'Slovakia', 'us': 'United States'}

Python演示


似乎不再起作用了,即使在您的演示代码中,输出也失败了:{'de': '德国', 'hu': '匈牙利', 'no': '挪威', 'sk': '斯洛伐克', 'us': '美国'} - manuelpgs
输出是预期的。您能否定义“输出失败”? - Pedro Lobito
预期输出如下所示:{ "de": "德国", "sk": "斯洛伐克", "hu": "匈牙利", "us": "美国", "no": "挪威" } - manuelpgs
当我打印d_sorted的类型时,它显示为“dict”,而不是OrderedDict。 - user11655900

2

您可以使用OrderedDict,但是必须考虑到OrderedDict在运行代码之外将无法工作。

这意味着将对象导出为JSON将失去OrderedDict的所有效果。

您可以创建一个元数据数组,在其中以有序方式存储键"de",sk"等。通过按顺序浏览数组,您可以正确引用字典,并且数组中的顺序将在任何导出JSON、YAML等的情况下保留。

当前JSON:

{ "de": "Germany", "sk": "Slovakia", "hu": "Hungary", "us": "United States", "no": "Norway"  }

新对象 countries

countries = {
  "names" : { 
    "de": "Germany", "sk": "Slovakia", "hu": "Hungary", "us": "United States", "no": "Norway"  
  },
  "order" : [ 
    "de", "sk", "hu", "us", "no" 
  ]
}

可以打印长名称并按顺序排列的代码:

for code in countries['order']:
 print(countries['names'][code])

实际上,您可以使用json.load()加载OrderedDict。有第二个参数告诉load方法创建一个OrderedDict对象以保持顺序相同。https://dev59.com/U2w05IYBdhLWcg3w9mdW - justdan23

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接