Странное поведение при обмене элементами в списках

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

list = [0, 1, ...., N-1]

Обмен происходит в двух циклах for (один для нечетных, один для четных), который выглядит следующим образом:

if odd:
    for exch in range(0, N / 2 -1 + N%2):
        index1 = list[2*exch+1]
        index2 = list[2*exch+2]
        some_conditions = function(index1, index2)
        print 'Trying to swap indexes ' + str(index1) + ' and ' + str(index2)
        if np.random.uniform(0,1) < some_conditions:
            list[index1], list[index2] = list[index2], list[index1]
            other[index1], other[index2] = other[index2], other[index1]
else:
    for exch in range(0, N / 2 ):
        index1 = list[2*exch]
        index2 = list[2*exch+1]
        some_conditions = function(index1, index2)
        print 'Trying to swap indexes ' + str(index1) + ' and ' + str(index2)
        if np.random.uniform(0,1) < some_conditions:
            list[index1], list[index2] = list[index2], list[index1]
            other[index1], other[index2] = other[index2], other[index1]    

Каким-то образом, когда происходит своп, python печатает один и тот же индекс дважды подряд, сообщая что-то вроде (это верно как для четных, так и для шансов):

Trying to swap index 0 and index 1
Trying to swap index 0 and index 4

Учитывая, что значения index1 и index2 уникальны, как Python может напечатать что-то вроде этого? На последующих шагах значение 0 не перепечатывается дважды, поэтому, вероятно, в памяти все нормально, но я не могу понять, почему он будет печатать дважды один и тот же индекс.

Я что-то здесь упускаю? Для справки, это расчет обмена репликами для молекулярной динамики на MPI, но обмен только на ранге 0. Это на python 2.7.

Редактировать: обновленное описание с нечетными и четными перестановками, чтобы сделать вещи немного понятнее. Причина, по которой у меня есть эта "странная" вещь, заключается в том, что мне нужно поменять местами значения, которые находятся рядом в другом списке, который соответствует некоторым параметрам моделирования. Например, если другое содержит:

other = [2, 3, 1, 4, 5]

Я попытаюсь поменять 1 с 2 и 3 на 4 для нечетного свопа, а затем для четного свопа, я попробую 2 с 3 и 4 с 5.

1 ответ

Вы делаете что-то странное здесь. Прежде всего, вы объявляете index1 и index2 в качестве значений внутри списка, а не фактических индексов.

index1 = list[2*exch+1]
index2 = list[2*exch+2]

Затем, когда вы говорите,

list[index1], list[index2] = list[index2], list[index1]

Вы фактически используете index1 и index2 в качестве индексов, когда они не являются фактическими индексами, они представляют собой значение внутри списка, поэтому, например, сначала index1 будет 0, а index2 будет 1, а затем вы поменяете их местами, второй раз index1 будет тем значением, которое вы сохранили в списке [3], а index2 будет значением в списке [4].

Это решит проблему, так как вам не нужно хранить значения для их изменения

for exch in range(0, N / 2 -1 + N%2):
index1 = 2*exch+1
index2 = 2*exch+2
some_conditions = function(index1, index2)
print 'Trying to swap indexes ' + str(index1) + ' and ' + str(index2)
if np.random.uniform(0,1) < some_conditions:
    list[index1], list[index2] = list[index2], list[index1]
Другие вопросы по тегам