问题:如何保持键/值与声明的顺序相同?

我有一本按照特定顺序声明的字典,并希望一直保持该顺序。键/值实际上不能根据它们的值按顺序保留,我只希望按声明的顺序保留。

因此,如果我有字典:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

如果我查看它或遍历它,则不是按此顺序进行的,有什么方法可以确保Python保持我声明键/值的显式顺序?

I have a dictionary that I declared in a particular order and want to keep it in that order all the time. The keys/values can’t really be kept in order based on their value, I just want it in the order that I declared it.

So if I have the dictionary:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

It isn’t in that order if I view it or iterate through it, is there any way to make sure Python will keep the explicit order that I declared the keys/values in?


回答 0

从Python 3.6开始,标准dict类型默认会保留插入顺序。

定义

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

将产生字典,其中的键按源代码中列出的顺序排列。

这是通过将一个带有整数的简单数组用于稀疏哈希表来实现的,其中这些整数索引到另一个存储键值对(加上计算得出的哈希值)的数组中。后面的数组恰好按插入顺序存储项目,实际上,整个组合使用的内存少于Python 3.5及之前版本中使用的实现。有关详细信息,请参阅Raymond Hettinger原始想法帖子

在3.6中,这仍被视为实现细节;请参阅Python 3.6文档的新增功能

此新实现的顺序保留方面被认为是实现细节,因此不应依赖(将来可能会更改,但是希望在更改语言规范之前,先在几个版本中使用该新dict实现该语言,为所有当前和将来的Python实现强制要求保留顺序的语义;这还有助于保留与仍旧有效的随机迭代顺序的旧版本语言(例如Python 3.5)的向后兼容性。

Python 3.7将此实现细节提升为语言规范,因此现在必须dict保留与该版本或更高版本兼容的所有Python实现中的顺序。参见BDFL的声明

在某些情况下,您可能仍想使用,因为它在标准dict类型的基础上提供了一些附加功能。例如是可逆的(这扩展到视图对象),并支持重新排序(通过move_to_end()方法)。

From Python 3.6 onwards, the standard dict type maintains insertion order by default.

Defining

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

will result in a dictionary with the keys in the order listed in the source code.

This was achieved by using a simple array with integers for the sparse hash table, where those integers index into another array that stores the key-value pairs (plus the calculated hash). That latter array just happens to store the items in insertion order, and the whole combination actually uses less memory than the implementation used in Python 3.5 and before. See the original idea post by Raymond Hettinger for details.

In 3.6 this was still considered an implementation detail; see the What’s New in Python 3.6 documentation:

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).

Python 3.7 elevates this implementation detail to a language specification, so it is now mandatory that dict preserves order in all Python implementations compatible with that version or newer. See the pronouncement by the BDFL.

You may still want to use the in certain cases, as it offers some additional functionality on top of the standard dict type. Such as as being reversible (this extends to the view objects), and supporting reordering (via the move_to_end() method).


回答 1

from collections import OrderedDict
OrderedDict((word, True) for word in words)

包含

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

如果值是True(或任何其他不可变对象),则还可以使用:

OrderedDict.fromkeys(words, True)
from collections import OrderedDict
OrderedDict((word, True) for word in words)

contains

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

If the values are True (or any other immutable object), you can also use:

OrderedDict.fromkeys(words, True)

回答 2

我不会解释理论部分,而是给出一个简单的示例。

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}

Rather than explaining the theoretical part, I’ll give a simple example.

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}

回答 3

请注意,此答案适用于python3.7之前的python版本。CPython 3.6在大多数情况下都将插入顺序作为实现细节来维护。从Python3.7开始,已经声明实现必须维护插入顺序以使其兼容。


python字典是无序的。如果需要有序字典,请尝试collections.OrderedDict

注意,OrderedDict是在python 2.7中引入的标准库。如果您使用的是python的旧版本,则可以在ActiveState上找到有序词典的食谱。

Note that this answer applies to python versions prior to python3.7. CPython 3.6 maintains insertion order under most circumstances as an implementation detail. Starting from Python3.7 onward, it has been declared that implementations MUST maintain insertion order to be compliant.


python dictionaries are unordered. If you want an ordered dictionary, try collections.OrderedDict.

Note that OrderedDict was introduced into the standard library in python 2.7. If you have an older version of python, you can find recipes for ordered dictionaries on ActiveState.


回答 4

字典将使用使搜索有效的顺序,您无法更改该顺序,

您可以只使用对象列表(在简单情况下为2元素元组,甚至是一个类),然后将项目附加到末尾。然后,您可以使用线性搜索在其中查找项目。

或者,您可以创建或使用为维护顺序而创建的其他数据结构。

Dictionaries will use an order that makes searching efficient, and you cant change that,

You could just use a list of objects (a 2 element tuple in a simple case, or even a class), and append items to the end. You can then use linear search to find items in it.

Alternatively you could create or use a different data structure created with the intention of maintaining order.


回答 5

我在尝试弄清楚如何使OrderedDict工作时遇到了这篇文章。用于Eclipse的PyDev根本找不到OrderedDict,所以我最终决定根据字典的键值创建一个元组,因为我希望对它们进行排序。当我需要输出列表时,我只需遍历元组的值,然后将元组中迭代的“键”插入字典中,即可按需要的顺序检索值。

例:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

这有点麻烦,但是我时间紧迫,这是我想出的解决方法。

注意:其他人建议的列表列表方法对我来说真的没有意义,因为列表是有序的和索引的(并且结构与字典不同)。

I came across this post while trying to figure out how to get OrderedDict to work. PyDev for Eclipse couldn’t find OrderedDict at all, so I ended up deciding to make a tuple of my dictionary’s key values as I would like them to be ordered. When I needed to output my list, I just iterated through the tuple’s values and plugged the iterated ‘key’ from the tuple into the dictionary to retrieve my values in the order I needed them.

example:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

It’s a tad cumbersome, but I’m pressed for time and it’s the workaround I came up with.

note: the list of lists approach that somebody else suggested does not really make sense to me, because lists are ordered and indexed (and are also a different structure than dictionaries).


回答 6

您实际上无法使用字典来完成所需的工作。您已经d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}创建了词典。我发现一旦创建就无法保持秩序。我所做的是用对象制作了一个json文件:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

我用了:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

然后使用:

print json.dumps(r)

核实。

You can’t really do what you want with a dictionary. You already have the dictionary d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}created. I found there was no way to keep in order once it is already created. What I did was make a json file instead with the object:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

I used:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

then used:

print json.dumps(r)

to verify.


回答 7

from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])
from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])

回答 8

另一种选择是使用Pandas,dataframe因为它可以保证像dict这样的结构中项目的顺序和索引位置。

Another alternative is to use Pandas dataframe as it guarantees the order and the index locations of the items in a dict-like structure.


回答 9

一般情况下,你可以设计一个类,像一本字典的行为,主要是实现方法__contains____getitem____delitem____setitem__和更多一些。该类可以具有您喜欢的任何行为,例如,对键使用排序的迭代器…

Generally, you can design a class that behaves like a dictionary, mainly be implementing the methods __contains__, __getitem__, __delitem__, __setitem__ and some more. That class can have any behaviour you like, for example prividing a sorted iterator over the keys …


回答 10

如果您希望按特定顺序拥有字典,则还可以创建一个列表列表,其中第一项为键,第二项为值,看起来像此示例

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

if you would like to have a dictionary in a specific order, you can also create a list of lists, where the first item will be the key, and the second item will be the value and will look like this example

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

回答 11

开发Django项目时遇到类似的问题。我无法使用OrderedDict,因为我正在运行旧版本的python,因此解决方案是使用Django的SortedDict类:

https://code.djangoproject.com/wiki/SortedDict

例如,

from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

注意:此答案最初来自2011年。如果您可以访问python 2.7或更高版本,则应该可以访问现在的standard collections.OrderedDict,该线程中的其他示例已经提供了其中的很多示例。

I had a similar problem when developing a Django project. I couldn’t use OrderedDict, because I was running an old version of python, so the solution was to use Django’s SortedDict class:

https://code.djangoproject.com/wiki/SortedDict

e.g.,

from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

Note: This answer is originally from 2011. If you have access to Python version 2.7 or higher, then you should have access to the now standard collections.OrderedDict, of which many examples have been provided by others in this thread.


回答 12

您可以做与字典一样的事情。

创建一个列表并清空字典:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', 'hima@gmail.com']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items

You can do the same thing which i did for dictionary.

Create a list and empty dictionary:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', 'hima@gmail.com']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。