Почему представление ключей OrderedDict не учитывает порядок?
почему OrderedDict
keys view сравнить порядок нечувствительным?
>>> from collections import OrderedDict
>>> xy = OrderedDict([('x', None), ('y', None)])
>>> yx = OrderedDict([('y', None), ('x', None)])
>>> xy == yx
False
>>> xy.keys() == yx.keys()
True
представление ключей OrderedDict должно, возможно, вести себя как OrderedSet, но вместо этого оно ведет себя так же, как dict.keys
(т. е. как обычный set
).
та же" проблема " в python2:
>>> xy.viewkeys() == yx.viewkeys()
True
это разные типы, (odict_keys
является наследником dict_keys
)
>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys
и уже сравнение чувствительных к заказу ключей доступно что они мог бы тривиально использоваться, но он, по-видимому, используется только как после проверки для сравнения odict rich.
это дизайнерское решение, или ошибка? Если это проектное решение, где я могу найти обсуждение обоснования?
2 ответов
выглядит так:OrderedDict
делегирует реализацию различных объектов представления общему dict
реализация; это остается так даже в Python 3.5, где OrderedDict
получил ускоренную реализацию C (он делегирует строительство объекта _PyDictView_New
и не дает переопределить для общего представления богатая функция сравнения.
по сути, OrderedDict
представления повторяются в том же порядке, что и их поддержка OrderedDict
будет (потому что это не стоит делать), но для set
-подобные операции, они действуют как set
, используя равенство контента, проверки подмножества / надмножества и т. д.
это делает выбор игнорировать порядок имеет смысл в некоторой степени; для некоторых set
операции (например,&
, |
, ^
), возвращаемое значение set
без порядка (потому что нет OrderedSet
, и даже если бы они были, какой заказ вы используете для чего-то вроде &
где заказ может отличаться в каждый вид?), вы получите непоследовательное поведение, если некоторые из set
-подобные операции были чувствительны к порядку, а некоторые-нет. И было бы еще страннее, если бы их было двое!--1--> представления ключей были чувствительны к порядку, но сравнение OrderedDict
вид dict
представления не было.
как я отметил в комментариях, вы можете получить чувствительный к заказу keys
сравнение довольно легко с:
from operator import eq
# Verify that keys are the same length and same set of values first for speed
# The `all` check then verifies that the known identical keys appear in the
# same order.
xy.keys() == yx.keys() and all(map(eq, xy, yx))
# If you expect equality to occur more often than not, you can save a little
# work in the "are equal" case in exchange for costing a little time in the
# "not even equal ignoring order case" by only checking length, not keys equality:
len(xy) == len(yz) and all(map(eq, xy, yx))
Я не могу найти ничего опубликованного, но я думаю, что эта логика может оправдать поведение:
если у вас есть два словаря, d1 и d2, вы ожидаете, что сравнение ключей проверяет, имеют ли они одинаковые ключи, верно?
def compare_dict_keys(d1, d2):
d1.keys() == d2.keys()
эта функция должна вести себя одинаково для любых типов словарей (и OrderedDict
тип dict
). Казалось бы, неправильно, если такая функция начала возвращать False
только потому, что D1 и d2 отсортированы.
In другими словами, все они должны оценивать одно и то же (и они это делают):
>>> {1:2, 3:4}.keys() == {3:4, 1:2}.keys()
True
>>> {1:2, 3:4}.keys() == OrderedDict([(3,4),(1,2)]).keys()
True
>>> OrderedDict([(1,2),(3,4)]).keys() == OrderedDict([(3,4),(1,2)]).keys()
True
но OrderedDict
это specal, не так ли?
что OrderedDict
предлагает вам гарантию заказа, когда вы повторяете его. Такая же гарантия существует для OrderedDict.keys()
, но без нарушения совместимости с dict
.