Гарантирует ли набор пересечений набор целых чисел для сортировки?
Я пытаюсь сделать огромное количество простых операций "пересечения" с целыми числами. К сожалению, в настройках нет numpy/scipy, и я не могу это изменить.
Я заметил в stackru, что операция множеств Python хорошо сортирует данные, что не только ускоряет загрузку дел, но и в моем случае, я на самом деле хотел бы также сортировать данные, таким образом, это был бы потрясающий бонус.
Я сейчас просто боюсь, что это не всегда работает, поэтому я пошел тестировать:
import random
one = range(100)
two = range(50)
three = range(50)
for i in xrange(1000000):
# shuffle the lists
random.shuffle(one)
random.shuffle(two)
# do set operation
res = [v for v in set(one) & set(two)]
if res != three:
print res
В результате все образцы сортируются (неправильные случаи не печатаются).
Хотя это довольно убедительно, я хотел бы знать, будет ли случай, когда целые числа не сортируются полностью при использовании пересечения множеств?
3 ответа
Нет, это не так.
Реализация пересечения множеств в CPython работает путем параллельной итерации по двум наборам в порядке хеширования. Соответствующие хэши дополнительно проверяются на равенство.
Если у вас есть набор небольших смежных int
s, они все будут хэшировать себе, так что все будет хорошо. Но если наборы - это что-то еще (широко расставленные целые, строки, что угодно), этот же эффект не появится.
Набор не имеет порядка, поэтому любой порядок является случайным. Или, если быть точным, у него есть некоторый порядок, но вы не можете делать никаких предположений относительно этого. Если вы хотите, чтобы результат был отсортирован, вам нужно отсортировать его самостоятельно, используя sorted()
,
Контрпримеры очень легко найти, если вы знаете, где искать
>>> [v for v in set(range(-10,0)) & set(range(-5,10))]
[-2, -5, -4, -3, -1]