В последнее время я заметил , что когда я Конвертирование list
в set
порядок элементов изменяются и сортируются по характеру.
Рассмотрим этот пример:
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
Мои вопросы -
- Почему это происходит?
- Как я могу выполнять операции с настройками (особенно с настройкой разницы), не теряя первоначального порядка?
unique = list(dict.fromkeys([1, 2, 1]).keys())
. Это работает, потому чтоdict
теперь порядок вставки сохраняется.Ответы:
A
set
- это неупорядоченная структура данных, поэтому она не сохраняет порядок вставки.Это зависит от ваших требований. Если у вас есть обычный список, и вы хотите удалить некоторый набор элементов, сохраняя порядок списка, вы можете сделать это с пониманием списка:
Если вам нужна структура данных, которая поддерживает как быстрые тесты членства, так и сохранение порядка вставки , вы можете использовать ключи словаря Python, который, начиная с Python 3.7, гарантированно сохраняет порядок вставки:
b
здесь действительно не нужно заказывать - вы также можете использоватьset
. Обратите внимание, чтоa.keys() - b.keys()
возвращает установленную разницу как aset
, поэтому порядок вставки не сохраняется.В старых версиях Python
collections.OrderedDict
вместо этого можно использовать :источник
None
синглтон с гарантированным языком. В CPython фактическая стоимость - это просто указатель (хотя эта стоимость всегда есть, но для dict вы можете почти считать, чтоNone
и другие одиночные или общие ссылки "бесплатными"), поэтому машинное слово, вероятно, 8 байт на современных компьютерах . Но да, это не так эффективно, как набор.dict.fromkeys([1, 2, 1]).keys()
потому что обычныйdict
порядок сохранения тоже.В Python 3.6есть другое решение для Python 2 и 3:set()
теперь должен сохраняться порядок, ноисточник
x.index
вызове выполняется линейный поиск. Если вас устраивает квадратичная сложность, вообще нет причин использовать aset
.set()
не упорядочено в Python 3.6, даже как деталь реализации, вы думаете оdict
sint
частоx=[1,2,-1,20,6,210]
сделать это набором. Вы увидите, что он вообще не заказан, протестирован в Python 3.6.Отвечая на ваш первый вопрос, набор - это структура данных, оптимизированная для операций с наборами. Как и математический набор, он не обеспечивает и не поддерживает какой-либо конкретный порядок элементов. Абстрактная концепция набора не обеспечивает порядок, поэтому реализация не требуется. Когда вы создаете набор из списка, Python имеет право изменять порядок элементов для нужд внутренней реализации, которую он использует для набора, который может эффективно выполнять операции над наборами.
источник
удалить дубликаты и сохранить порядок с помощью функции ниже
проверьте эту ссылку
источник
В математике есть множества и упорядоченные множества (oset).
В Python напрямую реализованы только наборы. Мы можем эмулировать oset с помощью обычных клавиш dict ( 3.7+ ).
Дано
Код
Демо
Реплики удаляются, порядок вставки сохраняется.
Операции, подобные множеству, над клавишами dict.
подробности
Примечание: неупорядоченная структура не препятствует упорядоченным элементам. Напротив, поддержание порядка не гарантируется. Пример:
Можно с удовольствием обнаружить, что список и мультимножество (mset) - это еще две увлекательные математические структуры данных:
Резюме
* Мультимножество может быть косвенно эмулировано с
collections.Counter()
помощью dict-подобного отображения кратностей (счетчиков).источник
Как указано в других ответах, наборы - это структуры данных (и математические концепции), которые не сохраняют порядок элементов -
Однако, используя комбинацию наборов и словарей, вы можете добиться того, чего захотите - попробуйте использовать эти фрагменты:
источник
Основываясь на ответе Свена, я обнаружил, что с помощью collections.OrderedDict, как так, помог мне выполнить то, что вы хотите, плюс разрешил мне добавить больше элементов в dict:
Если вы хотите добавить элементы, но при этом относитесь к ним как к набору, вы можете просто сделать:
И вы можете выполнить операцию вроде z.keys () над dict и получить набор:
источник
list(z.keys())
чтобы получить вывод списка.Реализация вышеизложенной концепции наивысшего балла, которая возвращает его в список:
Протестировано (кратко) на Python 3.6 и Python 2.7.
источник
В случае, если у вас есть небольшое количество элементов в ваших двух исходных списках, для которых вы хотите выполнить операцию установки разницы, вместо использования,
collections.OrderedDict
которое усложняет реализацию и делает ее менее читаемой, вы можете использовать:Его временная сложность не так хороша, но он аккуратный и легко читаемый.
источник
Интересно, что люди всегда используют «проблему реального мира», чтобы пошутить над определением в теоретической науке.
Если в наборе есть порядок, сначала нужно разобраться со следующими проблемами. Если в вашем списке есть повторяющиеся элементы, в каком порядке вы должны превратить его в набор? В каком порядке мы объединяем два множества? Каков порядок, если мы пересекаем два множества с разным порядком на одних и тех же элементах?
Кроме того, set намного быстрее при поиске определенного ключа, что очень хорошо для работы с наборами (и поэтому вам нужен набор, а не список).
Если вам действительно важен индекс, просто сохраните его в виде списка. Если вы все еще хотите выполнить операцию набора для элементов во многих списках, самый простой способ - создать словарь для каждого списка с одинаковыми ключами в наборе вместе со значением списка, содержащим весь индекс ключа в исходном списке.
источник
Вот простой способ сделать это:
источник