OrderedDict (Counter (s)) всегда будет давать заказанный словарь? - PullRequest
1 голос
/ 08 октября 2019

У меня есть код, подобный следующему, я хочу получить порядок, в котором вставлены ключи

from collections import Counter, OrderedDict
s = 'abcdabcd'
d = OrderedDict(Counter(s))
print(d)

вывод: OrderedDict([('a', 2), ('b', 2), ('c', 2), ('d', 2)])

Это правильный способ сделать это,мы можем получить один и тот же заказ при каждом запуске кода?

1 Ответ

1 голос
/ 08 октября 2019

Да, если вы неоднократно запускаете свой код, он будет выдавать тот же порядок , если вы используете Python 3.6 или новее .

Это потому, что итерирование по Counter() объектам всегда будет даватьВы в порядке вставка , и этот порядок определяется входными данными. Если ввод s не изменится, то не изменится и вывод OrderedDict(Counter(s)).

. Обратите внимание, что это порядок вставки ключей, а не порядок, производимый Counter.most_common();элементы не сортируются при переходе от Counter() к OrderedDict. Порядок остается стабильным, поскольку в Python 3.6 реализация словарей Python была изменена, чтобы использовать меньше памяти, и это, в свою очередь, имело побочный эффект записываемого порядка вставки. Начиная с Python 3.7, поддержание порядка вставки в словарях стало частью спецификации языка. См. Как сохранить ключи / значения в том же порядке, что и объявленный?

Таким образом, ключи перечислены в порядке их появления:

>>> from collections import Counter, OrderedDict
>>> OrderedDict(Counter("aaabbc"))
OrderedDict([('a', 3), ('b', 2), ('c', 1)])
>>> OrderedDict(Counter("abbccc"))
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> OrderedDict(Counter("cba"))
OrderedDict([('c', 1), ('b', 1), ('a', 1)])

Если вы хотите захватитьВ другом порядке, вам нужно отсортировать элементы перед передачей их объекту OrderedDict(). Например, для наиболее распространенного порядка (сначала самое высокое число), передайте результат Counter.most_common():

>>> s = "abbcaaacbbbbc"
>>> OrderedDict(Counter(s).most_common())
OrderedDict([('b', 6), ('a', 4), ('c', 3)])

Если люди задаются вопросом, почему вы все еще можете использовать OrderedDict: с этим типом вы можете повторноключи заказа (через OrderedDict.move_to_end()). Вы также можете использовать reversed() для упорядоченного дикта (а также для его словарных представлений).

(Примечание: я ошибся при первом наброске, после проверки я скорректировал этот ответ).

...