Подтвердить что ты не робот

Установка порядка итераций варьируется от запуска до запуска

Почему порядок итерации набора Python (с тем же содержимым) варьируется от run to run и каковы мои возможности для его согласования с запуском для запуска?

Я понимаю, что порядок итерации для набора Python произволен. Если я поставлю "a", "b" и "c" в набор, а затем повторю их, они могут вернуться в любом порядке.

То, что я наблюдал, заключается в том, что порядок остается неизменным во время запуска программы. То есть, если моя программа повторяет один и тот же набор дважды подряд, я получаю один и тот же порядок одновременно. Однако, если я запускаю программу дважды подряд, порядок изменяется от прогона до запуска.

К сожалению, это прерывает один из моих автоматических тестов, который просто сравнивает результаты двух запусков моей программы. Меня не волнует фактический порядок, но я бы хотел, чтобы он был последовательным от запуска до запуска.

Лучшее решение, которое я придумал, это:

  • Скопировать список в список.
  • Применить произвольный вид в список.
  • Итерировать список вместо установленного.

Есть ли более простое решение?

Примечание. Я нашел похожие вопросы в StackOverlow, но ни один из них не адресует эту конкретную проблему получения результатов от запуска для запуска.

4b9b3361

Ответ 1

То, что вы хотите, невозможно. Произвольное означает произвольное.

Мое решение будет таким же, как у вас, вам нужно отсортировать набор, если вы хотите сравнить его с другим.

Ответ 2

Используйте оператор symbric_difference (^) на ваших двух наборах, чтобы увидеть, есть ли различия:

In [1]: s1 = set([5,7,8,2,1,9,0])
In [2]: s2 = set([9,0,5,1,8,2,7])
In [3]: s1
Out[3]: set([0, 1, 2, 5, 7, 8, 9])
In [4]: s2
Out[4]: set([0, 1, 2, 5, 7, 8, 9])
In [5]: s1 ^ s2
Out[5]: set()

Ответ 3

Заданный порядок итерации зависит не только от его содержимого, но и от того, в каком порядке элементы были вставлены в набор, и были ли удалены по пути. Таким образом, вы можете создавать два разных набора, используя разные вставки и удаления, и заканчивать тем же набором в конце, но с разными порядками итерации.

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

Ответ 4

Ваш вопрос преобразуется в два вопроса: A) как сравнить "результат двух прогонов" в вашем конкретном случае; B) какое определение итерационного порядка в множестве. Может быть, вы должны отличить их и пост B) как новый вопрос, если это необходимо. Я отвечу A.

IMHO, используя отсортированный список в вашем случае, не очень чистое решение. Вы должны решить, будете ли вы соблюдать порядок итераций раз и навсегда и используйте соответствующую структуру.

Либо 1) вы хотите сравнить два набора, чтобы убедиться, что они имеют одинаковое содержимое, независимо от порядка. Тогда оператор simple == на множестве кажется подходящим. См. python2 sets, python3 устанавливает.

Или 2) вы хотите проверить, были ли элементы вставлены в том же порядке. Но это кажется разумным только в том случае, если порядок вставки как-то имеет значение для пользователей вашей библиотеки, и в этом случае использование типа набора было, вероятно, неприемлемым для начала. Иными словами, непонятно, что вы подразумеваете под "сравнением вывода двух прогонов" и почему вы хотите это сделать.

Во всех случаях я сомневаюсь, что отсортированный список здесь подходит.

Ответ 5

Причина, по которой изменился порядок итераций при запуске, заключается в том, что Python по умолчанию использует рандомизацию хеш-семян. (См. Опцию команды -R.) Таким образом, итерация не является произвольной (из-за хэширования), но также недетерминированной (из-за случайное семя).

Вы можете переопределить случайное семя с фиксированным значением, установив для интерпретатора переменную окружения PYTHONHASHSEED. Использование одного и того же семени из run to run означает, что итерация по-прежнему произвольна, но теперь она детерминирована, и это было искомое свойство.

Рандомизация семян хеширования - это мера безопасности, которая затрудняет для противника противодействие входам, которые будут вызывать патологическое поведение (например, путем создания многочисленных столкновений с хэшем). Для модульного тестирования это не вызывает беспокойства, поэтому разумно переопределять семена хеша при выполнении тестов.

Ответ 6

Вы можете установить ожидаемый результат как набор. И проверяет, равны ли эти два набора, используя ==.

Ответ 7

В отличие от наборов, списки всегда имеют гарантированный порядок, поэтому вы можете бросить набор и использовать список.