Вы не можете использовать кортеж для индексации списка. Используйте две отдельные операции индексирования для замены двух индексов:
sequence[swap_index], sequence[next_index] = sequence[next_index], sequence[swap_index]
Обратите внимание, что ваш тест swap_index != sequence_len
никогда не будет верным, поскольку secrets.randbelow()
уже гарантирует, что вы получите значение от 0 до ниже значения аргумента. Вы столкнетесь с ошибкой индекса, когда swap_index
равен sequence_len - 1
, потому что тогда next_index
устанавливается равным sequence_len
, что не является допустимым индексом.
Далее, если sequence
является неизменяемым типом, например строкой, то присвоение индексам не может работать. Сначала вам нужно будет преобразовать строку в изменяемую последовательность, например, список, затем преобразовать обратно в строку (используя str.join()
).
И, наконец, ваша реализация меняет местами только последовательные элементы, что не совсем правильно. Вы должны рассмотреть все элементы, которые еще не поменялись местами.
И, наконец, чтобы «перетасовать» последовательность «безопасно», просто используйте класс secrets.SystemRandom()
и назовите его shuffle()
метод :
from secrets import SystemRandom
sysrandom = SystemRandom()
def shuffle_sequence(sequence):
sequence = list(sequence)
sysrandom.shuffle(sequence)
return ''.join(sequence)
Реализация для Random.shuffle()
перебирает индексы последовательности в обратном порядке и выбирает случайный элемент, который находится перед индексом итерации:
for next_index in reversed(range(1, sequence_len)):
swap_index = random.randbelow(next_index)
sequence[swap_index], sequence[next_index] = sequence[next_index], sequence[swap_index]