Использование упорядоченного словаря в качестве упорядоченного набора - PullRequest
0 голосов
/ 03 июля 2018

Теперь, когда Python 3.7 делает сохраняющие порядок слова официально частью спецификации языка вместо деталей реализации, я пытался обдумать, как лучше всего использовать это свойство. Сегодня я обнаружил, что мне нужен набор для сохранения порядка, и думаю, что словарь может сработать.

Предположим, у нас есть список хэшируемых элементов. Нам нужен список уникальных записей, и мы хотим сохранить порядок этих записей на основе первого появления. Простой конструктор словаря должен сделать трюк:

ls = "Beautiful is better than ugly. Explicit..."
uniques = list({s:0 for s in ls})

>>> ['B', 'e', 'a', 'u', 't', 'i', 'f', 'l', ' ', 's', 'b', 'r', 'h', 'n', 'g', 'y', '.', 'E', 'x', 'p', 'c']

Это сохранит порядок при первом появлении и избавит от всех дубликатов.

Я хотел бы знать, что сообщество думает об этом сценарии использования и о функции сохранения порядка в целом.

  • Есть ли причина, по которой этот метод не следует использовать?
  • Есть ли лучшие способы решить эту проблему?
  • Является ли этот метод Pythonic?

Читая дзен Python, я в конфликте. Метод прост, но основан на неявном упорядочении.

Пожалуйста, дайте мне знать, что вы думаете. Спасибо.

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Это прекрасно работает на Python 3.7! .. но Python 3.7 - не единственная версия Python. Полагаться на сохранение порядка диктов довольно долго будет опасной привычкой, потому что, если ваш код когда-либо будет работать на версии Python до 3.6, он полностью перестанет поддерживать порядок.

Использование, скажем, dataclasses или contextvars не так уж опасно, потому что если вы попытаетесь запустить код, основанный на dataclasses на Python, который не имеет dataclasses, вы получите большой, чистый ImportError. Дики, теряющие свой порядок, не имеют такой же очевидности.

Возможно, вы даже не подозреваете, что он прекратил поддерживать порядок. Возможно, вы не помните, что полагались на диктат Вы можете забыть задокументировать или сообщить кому-либо, что вы полагались на него, или вы можете быть плохим программистом, который наследует код, когда кто-то полагался на порядок, без документирования требования Python 3.7+. Вы можете даже не догадываться, что вы забыли обновить Python на одной конкретной машине или что вы случайно вышли из Anaconda или чего-то еще, и вы работаете в системе Python 3, которая все еще использует 3.4.

Будет безопасно принять в конечном итоге приказ. На данный момент, особенно прямо сейчас , через несколько дней после выпуска 3.7, лучше использовать OrderedDict или добавить проверку версии:

import collections
import sys

_make_ordered_mapping = (dict.fromkeys if sys.version_info >= (3, 7)
                         else collections.OrderedDict.fromkeys)

def ordered_dedup(items):
    return list(_make_ordered_mapping(items))
0 голосов
/ 03 июля 2018

Этот подход использования словаря Python 3.7 в качестве средства сохранения порядка проверяется основным разработчиком Python здесь . Вы не можете получить лучшую рекомендацию, чем эта.

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

номер

Есть ли лучшие способы решить эту проблему?

номер

Является ли этот метод Pythonic?

Да.

Метод прост, но основан на неявном упорядочении.

Ваш вопрос помечен как python-3.7. Словари, сохраняющие порядок вставки, гарантированы, поэтому здесь нет неявного упорядочения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...