Найти - Пользователи
Полная версия: как отключить сортировку dict-а ?
Начало » Python для новичков » как отключить сортировку dict-а ?
1
umup
возможно ли отключить сортировку dict-а - нужен перебор ключей не в алфавитном порядке, а порядке, заданном при создании dict-a.
nss
Нет, нельзя. Dict это бинарное дерево.

Можно сделать свой тип с методами __getitem__ и __setitem__, с которым можно будет работать как с обычным dict'ом. Но он будет гораздо медленнее.
umup
nss
Нет, нельзя. Dict это бинарное дерево.
Можно сделать свой тип с методами __getitem__ и __setitem__, с которым можно будет работать как с обычным dict'ом. Но он будет гораздо медленнее.
мда… плохо.
значить придется через list dictов, но поиск по текстовым полям будет медленный.
umup
хотя.. сделаю для каждого dictа свой list с ключами, отсортированными в нужном порядке.
Андрей Светлов
Это пример из sqlalchemy

sqlalchemy.utils


class OrderedDict(dict):
“”“A Dictionary that returns keys/values/items in the order they were added.”“”

def __init__(self, ____sequence=None, **kwargs):
self._list =
if ____sequence is None:
self.update(**kwargs)
else:
self.update(____sequence, **kwargs)

def clear(self):
self._list =
dict.clear(self)

def update(self, ____sequence=None, **kwargs):
if ____sequence is not None:
if hasattr(____sequence, ‘keys’):
for key in ____sequence.keys():
self.__setitem__(key, ____sequence)
else:
for key, value in ____sequence:
self = value
if kwargs:
self.update(kwargs)

def setdefault(self, key, value):
if key not in self:
self.__setitem__(key, value)
return value
else:
return self.__getitem__(key)

def __iter__(self):
return iter(self._list)

def values(self):
return [self for key in self._list]

def itervalues(self):
return iter(self.values())

def keys(self):
return list(self._list)

def iterkeys(self):
return iter(self.keys())

def items(self):
return [(key, self) for key in self.keys()]

def iteritems(self):
return iter(self.items())

def __setitem__(self, key, object):
if key not in self:
self._list.append(key)
dict.__setitem__(self, key, object)

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

def pop(self, key):
value = dict.pop(self, key)
self._list.remove(key)
return value

def popitem(self):
item = dict.popitem(self)
self._list.remove(item)
return item



Кажется, то, что нужно. Незачем кодить самому.
Можно просто взять готовое. То, что хотел - ну уже реализованное.
Свой порядок легко сюда вставить. Если в self._list добавлять и удалять через bisect - получишь dict, упорядоченный по твоим правилам.
Заметь, __getitem__ не перегружается - т.е. поиск по ключу быстр так же, как и в dict.

Если keys/iterkeys, values/itervalues, items/iteritems переставить - сначала генератор, а только потом из него список - выйдет еще быстрее.
Вроде того:

def values(self):
return list(self.itervalues())

def itervalues(self):
return (self for key in self._list)

def keys(self):
return list(self.iterkeys())

def iterkeys(self):
return iter(self._list)

def items(self):
return self.iteritems()

def iteritems(self):
return ((key, self) for key in self.iterkeys())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB