Set Popping (Python) - PullRequest
       15

Set Popping (Python)

10 голосов
/ 24 марта 2012

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

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

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

Ответы [ 2 ]

16 голосов
/ 24 марта 2012

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

Пример:

>>> foo = set()
>>> foo.add(-3)
>>> foo.add(-1)
>>> foo.add(2)
>>> foo.pop()
2
>>> foo.pop()
-3
15 голосов
/ 24 марта 2012

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

Заказ, который вы видите, является негарантированной деталью реализации. В 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 выскакивает записи слева направо. Это также не гарантированная деталь реализации.

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

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

...