Как известно стандартный словарь питона не поддерживает сортировку ключей. Данная проблема просто решается небольшим модулем odict от небезызвестного Армина Ронахера - автора Flask, Jinja2, одного из основателей pocoo (www.pocoo.org). Скачать пакет можно здесь https://pypi.python.org/pypi/odict/1.5.1
odict - обвертка над стандартным словарем с небольшой костомизацией.
Вся "магия" заключена в двух следующих методах:
Первоначально формируется значение ключа - список, содержащий три значения - предыдущий ключ словаря, значение текущего ключа, ключ следующего значения. Искушенный читатель уже догадался - это классический double linked list.
lh и lt - простые свойства, хранящие ключ головного и последнего элемента
Генератор, возвращающий атрибуты в том порядке, в котором они поступили.
PS Код Армин как всегда элегантен и прост. Более подробно об odict можно почитать на github https://github.com/bluedynamics/odict
Пробуем
>>> odict.odict((('first', 1), ('second', 2))).items()
[('first', 1), ('second', 2)]
>>> odict.odict((('first', 1), ('second', 2))).as_dict()
{'second': 2, 'first': 1}
Как это работает
Код Армина всегда отличался элегантностью и простотой, поэтому я не удержался чтобы заглянуть по капот odict.odict - обвертка над стандартным словарем с небольшой костомизацией.
Вся "магия" заключена в двух следующих методах:
def __setitem__(self, key, val):dict_impl = self._dict_impl() //здесь возвращается стандартный словарьtry:dict_impl.__getitem__(self, key)[1] = valexcept KeyError:new = [dict_impl.__getattribute__(self, 'lt'), val, _nil]dict_impl.__setitem__(self, key, new)if dict_impl.__getattribute__(self, 'lt') == _nil:dict_impl.__setattr__(self, 'lh', key)else:dict_impl.__getitem__(self, dict_impl.__getattribute__(self, 'lt'))[2] = keydict_impl.__setattr__(self, 'lt', key)
Первоначально формируется значение ключа - список, содержащий три значения - предыдущий ключ словаря, значение текущего ключа, ключ следующего значения. Искушенный читатель уже догадался - это классический double linked list.
lh и lt - простые свойства, хранящие ключ головного и последнего элемента
def iteritems(self):dict_impl = self._dict_impl()curr_key = dict_impl.__getattribute__(self, 'lh')while curr_key != _nil:_, val, next_key = dict_impl.__getitem__(self, curr_key)yield curr_key, valcurr_key = next_key
Генератор, возвращающий атрибуты в том порядке, в котором они поступили.
PS Код Армин как всегда элегантен и прост. Более подробно об odict можно почитать на github https://github.com/bluedynamics/odict
Комментариев нет:
Отправить комментарий