Установить Popping (Python)

Допустим, у вас есть набор:

foo = {1, 2, 3, 4, 5}

В книге, которую я сейчас читаю, Pro Python, говорится, что использование foo.pop() будет вызывать произвольное число из этого выбора. НО... Когда я это пробовал, он pops 1, then 2, then 3... Делает ли это это произвольно, или это просто совпадение?

Ответ 1

Причина, по которой она говорит, что она произвольна, заключается в том, что нет гарантии о том, что она выскочит. Поскольку вы только что создали набор, он может хранить элементы в "хорошем" порядке, и, таким образом, .pop() происходит, чтобы вернуть их в этом порядке, но если вы должны были мутировать набор, это может не продолжаться.

Пример:

>>> foo = set()
>>> foo.add(-3)
>>> foo.add(-1)
>>> foo.add(2)
>>> foo.pop()
2
>>> foo.pop()
-3

Ответ 2

Набор и словари реализуются с использованием хеш-таблиц. Это неупорядоченные коллекции, что означает, что у них нет гарантированного порядка.

Приказ, который вы видите, представляет собой не гарантированную деталь реализации. В CPython хеш-значение для целого является самим целым:

>>> [hash(i) for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Эта деталь реализации заставляет целые числа отображаться упорядоченными в вашем наборе. Другие наборы будут полуупорядочены, {5, 6, 7, 8, 9} отображается как set([8, 9, 5, 6, 7]).

Напротив, другие типы данных, такие как str, имеют разные хэш-функции и, как представляется, более скремблированы. Например:

# Example of scrambling str objects in a 64-bit build
>>> {'red', 'green', 'blue'}
set(['blue', 'green', 'red'])

Метод set.pop выдает записи слева направо. Это также не гарантированная деталь реализации.

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

Надеюсь, что это очистит тайну для вас:-)