Лучший способ перетасовать два связанных списка
Есть ли лучшие способы случайного перетасовки двух связанных списков, не нарушая их переписки в другом списке? Я нашел связанные вопросы в 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]
Просто найдите это немного неудобно. А также нужен дополнительный список.
Ответы
Ответ 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.