Как правильно инициализировать упорядоченный словарь (OD), чтобы он сохранял порядок исходных данных?
from collections import OrderedDict
# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1})
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])
# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])
Вопрос:
Будет ли
OrderedDict
сохранен порядок списка кортежей, кортежа кортежей или кортежа списков или списка списков и т.д., переданных во время инициализации (2-й и 3-й примеры выше)?Как можно проверить,
OrderedDict
действительно ли поддерживается заказ? Поскольку adict
имеет непредсказуемый порядок, что, если мои тестовые векторы, к счастью, имеют тот же начальный порядок, что и непредсказуемый порядок dict? Например, если вместо того, чтобыd = OrderedDict({'b':2, 'a':1})
писатьd = OrderedDict({'a':1, 'b':2})
, я могу ошибочно сделать вывод, что порядок сохраняется. В этом случае я обнаружил, что adict
упорядочен по алфавиту, но это может быть не всегда так. Какой надежный способ использовать контрпример для проверки того, сохраняет ли структура данных порядок или нет, кроме многократных попыток тестовых векторов, пока один из них не сломается?
PS Я просто оставлю это здесь для справки : «Конструктор OrderedDict и метод update () оба принимают аргументы ключевого слова, но их порядок теряется, потому что аргументы ключевого слова передачи семантики функции Python используют обычный неупорядоченный словарь»
PPS: Надеюсь, что в будущем OrderedDict также сохранит порядок kwargs (пример 1): http://bugs.python.org/issue16991
OrderDict(b=2, a=1)
это тоже правильный путь. См. PEP 468 .Ответы:
OrderedDict сохранит любой порядок, к которому у него есть доступ. Единственный способ передать ему упорядоченные данные для инициализации - это передать список (или, в более общем смысле, итерацию) пар ключ-значение, как в ваших последних двух примерах. Как говорится в документации, на которую вы ссылаетесь, OrderedDict не имеет доступа к какому-либо порядку, когда вы передаете аргументы ключевого слова или аргумент dict, поскольку любой порядок там удаляется до того, как его увидит конструктор OrderedDict.
Обратите внимание, что использование списка в вашем последнем примере ничего не меняет. Нет разницы между
OrderedDict([(i,i) for i in l])
иOrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
. Понимание списка оценивается и создает список, который передается; OrderedDict ничего не знает о том, как он был создан.источник
Да, это сработает. По определению список всегда упорядочен так, как он представлен. Это также относится к пониманию списка, список создается таким же образом, как и данные (т.е. источник из списка будет детерминированным, полученным из a
set
илиdict
не так много).Вы храните свой исходный список из двух кортежей для справки и используете его в качестве тестовых данных для своих тестовых случаев при выполнении модульных тестов. Просмотрите их и убедитесь, что порядок сохраняется.
источник
__hash__
. Конкретно оstr
типе.OrderedDict
чтобы у меня не было накладных расходов на преобразование списка в файлOrderedDict
. Я просто перебираю элементы как список вместо словаря.