Как получить элементы из словаря в том порядке, в котором они вставлены?

Можно ли получить элементы из словаря Python в том порядке, в котором они были вставлены?

возможный дубликат Почему значения словаря не во вставленном порядке?

nbro 10.01.2015 04:52

Этот вопрос (и устаревший принятый ответ) по-прежнему является результатом №1 поиска в Google «элементов Python dict по порядку вставки». Если вы читаете это, проголосуйте за ответ Брайана 2018 года.

Rakurai 02.01.2019 21:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
60
2
43 384
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Вы не можете сделать это с базовым классом dict - он упорядочен по хешу. Вы можете создать свой собственный словарь, который на самом деле представляет собой список пар ключей, значений или чего-то подобного, которые будут упорядочены.

Вместо этого ваша реализация словаря может использовать стандартный словарь и список - словарь хранит ассоциации ключ-> значение, а список хранит ключи в том порядке, в котором они вставлены.

Binil Thomas 14.09.2008 01:56
Ответ принят как подходящий

Стандартный Python dict делает это по умолчанию, если вы используете CPython 3.6+ (или Python 3.7+ для любой другой реализации Python).

В более старых версиях Python вы можете использовать collections.OrderedDict.

Кажется, что этот ответ был обновлен в соответствии с последним правильным ответом (который также является ответом Брайана), поэтому приведенные выше комментарии больше не актуальны.

justhalf 01.07.2019 22:24

Остальные ответы верны; это невозможно, но вы можете написать это сами. Однако, если вы не знаете, как на самом деле реализовать что-то подобное, вот полная и рабочая реализация, диктуемая подклассами, которую я только что написал и протестировал. (Обратите внимание, что порядок значений, переданных в конструктор, не определен, но будет предшествовать значениям, переданным позже, и вы всегда можете просто не разрешить инициализацию упорядоченных диктовок значениями.)

class ordered_dict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self._order = self.keys()

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        if key in self._order:
            self._order.remove(key)
        self._order.append(key)

    def __delitem__(self, key):
        dict.__delitem__(self, key)
        self._order.remove(key)

    def order(self):
        return self._order[:]

    def ordered_items(self):
        return [(key,self[key]) for key in self._order]


od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order()            # prints ['hello', 'goodbye']

del od["hello"]
od["monty"] = "python"
print od.order()            # prints ['goodbye', 'monty']

od["hello"] = "kitty"
print od.order()            # prints ['goodbye', 'monty', 'hello']

print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]

Правильно ли заказан order_dict (('key_a', 'value_a'), ('key_b', 'value_b'))? Похоже, что _order будет установлен на self.keys () в в этом, который упорядочен в порядке хеширования, а не в том порядке, в котором он был введен? Просто любопытно.

Brian M. Hunt 09.12.2008 23:57

Вы правы, поэтому я сказал: «Порядок значений, передаваемых в конструктор, не определен, но будет до значений, переданных позже». Их можно было бы правильно заказать, но я не был уверен, было ли это желаемым поведением, поскольку, возможно, такие объекты вставляются одновременно.

Eli Courtwright 11.12.2008 01:13

если вам не нужны функции dict и вам нужно возвращать кортежи только в том порядке, в котором вы их вставили, не будет ли очередь работать лучше?

Раньше я успешно использовал StableDict.

http://pypi.python.org/pypi/StableDict/0.2

Или просто сделайте ключ кортежем с time.now () в качестве первого поля в кортеже.

Затем вы можете получить ключи с помощью dictname.keys (), sort и вуаля!

Джерри

Это делает невозможным поиск записей в dict, не зная точно, когда вы их вставили. Это не лучше, чем список пар ключ-значение.

user2357112 supports Monica 04.06.2014 07:03

Это невозможно, если вы не сохраните ключи в отдельном списке для использования позже.

Или используйте любую из реализаций для PEP-372, описанных здесь, например модуль odict из pythonutils.

Я успешно использовал реализацию pocoo.org, это так же просто, как заменить ваш

my_dict = {}
my_dict["foo"] = "bar"

с

my_dict=odict.odict()
my_dict["foo"] = "bar"

и требуется только этот файл

Что вы можете сделать, так это вставить значения с помощью ключа, представляющего введенный порядок, а затем вызвать sorted() для элементов.

>>> obj = {}
>>> obj[1] = 'Bob'
>>> obj[2] = 'Sally'
>>> obj[3] = 'Joe'
>>> for k, v in sorted(obj.items()):
...     print v
... 
Bob
Sally
Joe
>>> 

Если бы нам еще не понадобился ключ для других целей, мы бы использовали список. Это не делает ничего лучше, чем список.

user2357112 supports Monica 04.06.2014 06:53

@ user2357112, однако, это выражает другой метод выполнения что ОП спросил. OP не спрашивал, как печатать элементы в том порядке, в котором они были вставлены, OP сказал, как печатать элементы в dict. Большая разница.

A.J. Uppal 04.06.2014 06:56

Однако вы изменили формат словаря до такой степени, что он стал бесполезным для первоначальной цели. Если dict изначально связывает, скажем, имена с телефонными номерами, вы получили постоянный порядок итераций, но вы не знаете, какой номер телефона у Боба.

user2357112 supports Monica 04.06.2014 06:57

Используйте OrderedDict (), доступный с версии 2.7.

Просто любопытство:

from collections import OrderedDict
a = {}
b = OrderedDict()
c = OrderedDict()

a['key1'] = 'value1'
a['key2'] = 'value2'

b['key1'] = 'value1'
b['key2'] = 'value2'

c['key2'] = 'value2'
c['key1'] = 'value1'

print a == b  # True
print a == c  # True
print b == c  # False

Начиная с Python 3.7, стандартный dict сохраняет порядок вставки. Из документы:

Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was implementation detail of CPython from 3.6.

Итак, вы должны иметь возможность перебирать словарь в обычном режиме или использовать popitem().

Давайте проголосуем за этот ответ. Дополнительно из документации, раздел 5.5 Словари: «Выполнение list (d) в словаре возвращает список всех ключей, используемых в словаре, в порядке вставки (если вы хотите, чтобы он был отсортирован, просто используйте вместо этого sorted (d))».

Rakurai 02.01.2019 20:59

Другие вопросы по теме