Как вы получаете элементы из словаря в порядке их вставки?
Можно ли извлечь элементы из словаря Python в том порядке, в котором они были вставлены?
11 ответов
Стандартный питон dict
не в состоянии сделать это.
Существует предложение ( PEP 372) добавить "упорядоченный словарь" (который отслеживает порядок вставки) к collections
модуль в стандартной библиотеке. Он включает ссылки на различные реализации упорядоченных словарей (см. Также эти два рецепта в Python Cookbook).
Возможно, вы захотите придерживаться эталонной реализации в PEP, если хотите, чтобы ваш код был совместим с "официальной" версией (если предложение в конечном итоге будет принято).
РЕДАКТИРОВАТЬ: PEP был принят и добавлен в Python 2.7 и 3.1. Смотрите документы.
Начиная с Python 3.7, стандартный dict сохраняет порядок вставки. Из документов:
Изменено в версии 3.7: Порядок словаря гарантированно является порядком вставки. Такое поведение было деталью реализации CPython от 3.6.
Таким образом, вы должны иметь возможность перебирать словарь в обычном режиме или использовать popitem()
,
Используйте 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
Другие ответы верны; это невозможно, но вы можете написать это сами. Однако, в случае, если вы не знаете, как на самом деле реализовать что-то подобное, вот полная и работающая реализация, которая диктует подклассы, которые я только что написал и протестировал. (Обратите внимание, что порядок значений, передаваемых в конструктор, не определен, но он будет предшествовать значениям, переданным позже, и вы всегда можете просто не допустить, чтобы упорядоченные dict инициализировались значениями.)
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')]
Или просто сделайте ключ кортежем с помощью time.now() в качестве первого поля в кортеже.
Затем вы можете получить ключи с помощью dictname.keys(), sort и вуаля!
Gerry
Вы не можете сделать это с базовым классом dict - он упорядочен по хешу. Вы можете создать свой собственный словарь, который на самом деле представляет собой список ключей, пар значений или чего-то подобного, который будет упорядочен.
Я использовал StableDict раньше с хорошим успехом.
Или используйте любую из реализаций для 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
>>>
Если вам не нужны функции dict и нужно возвращать кортежи в том порядке, в котором вы их вставили, разве очередь не будет работать лучше?