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

Лучший способ перетасовать два связанных списка

Есть ли лучшие способы случайного перетасовки двух связанных списков, не нарушая их переписки в другом списке? Я нашел связанные вопросы в numpy.array и c#, но не совсем то же самое.

Как первая попытка, простой трюк zip будет делать:

import random
a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
b = [2, 4, 6, 8, 10]
c = zip(a, b)
random.shuffle(c)
a = [e[0] for e in c]
b = [e[1] for e in c]
print a
print b

Он получит результат:

[[1, 2], [7, 8], [3, 4], [5, 6], [9, 10]]
[2, 8, 4, 6, 10]

Просто найдите это немного неудобно. А также нужен дополнительный список.

4b9b3361

Ответ 1

Учитывая взаимосвязь, продемонстрированную в этом вопросе, я собираюсь предположить, что списки имеют одинаковую длину, и что list1[i] соответствует list2[i] для любого индекса i. При таком допущении перетасовка списков так же проста, как перетасовка индексов:

 from random import shuffle
 # Given list1 and list2

 list1_shuf = []
 list2_shuf = []
 index_shuf = list(range(len(list1)))
 shuffle(index_shuf)
 for i in index_shuf:
     list1_shuf.append(list1[i])
     list2_shuf.append(list2[i])

Ответ 2

Если вы хотите установить еще несколько пакетов:

Req: NumPy ( >= 1,6,1), SciPy ( >= 0,9).

pip install -U scikit-learn

from sklearn.utils import shuffle
list_1, list_2 = shuffle(list_1, list_2)

Ответ 3

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

Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
>>> b = [2, 4, 6, 8, 10]
>>> indexes = range(len(a))
>>> indexes
[0, 1, 2, 3, 4]
>>> random.shuffle(indexes)
>>> indexes
[4, 1, 2, 0, 3]
>>> for index in indexes:
...     print a[index], b[index]
...
[9, 10] 10
[3, 4] 4
[5, 6] 6
[1, 2] 2
[7, 8] 8

Ответ 4

До сих пор все решения создавали новые списки для решения проблемы. Если списки a и b очень длинные, вы можете перетасовать их на место. Для этого вам понадобится такая функция, как:

import random

def shuffle(a,b):
    assert len(a) == len(b)
    start_state = random.getstate()
    random.shuffle(a)
    random.setstate(start_state)
    random.shuffle(b)

a = [1,2,3,4,5,6,7,8,9]
b = [11,12,13,14,15,16,17,18,19]
shuffle(a,b)
print(a) # [9, 7, 3, 1, 2, 5, 4, 8, 6]
print(b) # [19, 17, 13, 11, 12, 15, 14, 18, 16]

Ответ 5

Быстрый ответ, используя numpy, см. здесь:
Вы можете использовать

p = numpy.random.permutation(len(a))

Чтобы создать новый список индексов для обоих списков и использовать его для их изменения.

В вашем сценарии:

In [61]: a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
In [62]: b = [2, 4, 6, 8, 10]
In [63]: import numpy as np
In [64]: a_ar, b_ar = np.array(a), np.array(b)
In [65]: p = np.random.permutation(len(a))
In [66]: a, b = a_ar[p].tolist(), b_ar[p].tolist()
In [68]: a
Out[68]: [[3, 4], [7, 8], [5, 6], [1, 2], [9, 10]]
In [69]: b
Out[69]: [4, 8, 6, 2, 10]

Ответ 6

Вы можете распаковать в конце, чтобы немного ограничить неловкость?

import numpy as np
list1 = [1,2,3]
list2 = [4,5,7]
list_zipped = list(zip(list1,list2))
np.random.shuffle(list_zipped)
list1,list2 = zip(*z) #unzipping

Ответ 7

Я не уверен, что здесь что-то не хватает, но похоже, что вы просто перетасовываете 1 из списков, а другой перенастраивается, чтобы соответствовать порядку первого списка. Так что у вас есть лучший способ сделать это, не усложняя его. Если вы хотите пойти по сложному маршруту, вы можете просто перетасовать 1 список и использовать незашифрованный список, чтобы выполнить поиск в перетасованном списке и переупорядочить его таким образом. В итоге вы получаете тот же результат, с которого вы начали. Почему создается третий список проблем? Если вы действительно хотите перерабатывать списки, вы можете просто заменить список b тем, что вы используете для списка c, а затем разделить его позже на a и b.