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

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

Ответ 1

Стандартный питон dict не может этого сделать.

Существует предложение (PEP 372), чтобы добавить "упорядоченный словарь" (который отслеживает порядок вставки) в collections в стандартной библиотеке. Он включает ссылки на различные реализации упорядочено словари (см. также эти два recipes в Поваренной книге Python).

Возможно, вы захотите придерживаться эталонной реализации в PEP, если хотите, чтобы ваш код был совместим с "официальной" версией (если предложение в конечном итоге принято).

EDIT: PEP был принят и добавлен в python 2.7 и 3.1. Смотрите документы.

Ответ 2

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

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')]

Ответ 3

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

Ответ 4

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

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

Герри

Ответ 5

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

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

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

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

Ответ 7

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

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

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

с

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

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

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