Как перетасовать список в Python

Я выполняю операции перетасовки во вложенных списках в Python 3. Я хочу бесконечно перетасовывать ранее перемешанные списки, пока порядок вложенных списков не будет соответствовать определенным критериям. random.shuffle работает на месте, и вызов random.shuffle() в ранее перемешанном списке не перетасовывает его. Как лучше всего перетасовывать список до бесконечности, пока он не выполнит условие. Например, я пытался что-то вроде этого, но создание нового списка, а затем его перетасовка, похоже, не работает:

from random import shuffle

L1 = [[1,2], [3,4], [5,6], [7,8], [9,10]]
shuffle(L1)
match = L1[0]

# reshuffle until [9,10] is the first item in the list
if match != [9,10]:
    L1 = list(L1)
    shuffle(L1)
print(L1)

person drbunsen    schedule 05.12.2011    source источник


Ответы (2)


Это утверждение:

вызов random.shuffle() в ранее перемешанном списке не перетасовывает его

Это неправильно. Наблюдать:

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> L1 = [[1,2], [3,4], [5,6], [7,8], [9,10]]
>>> from random import shuffle
>>> shuffle(L1)
>>> print L1
[[3, 4], [9, 10], [5, 6], [7, 8], [1, 2]]
>>> shuffle(L1)
>>> print L1
[[9, 10], [3, 4], [5, 6], [1, 2], [7, 8]]
>>> 

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

from random import shuffle

L1 = [[1,2], [3,4], [5,6], [7,8], [9,10]]
match = [9,10]
while L1[0]!=match:
    shuffle(L1)
print(L1)
person Francis Avila    schedule 05.12.2011
comment
Правильно, поэтому я копирую список L1 = list(L1) - person drbunsen; 05.12.2011
comment
Список копировать не нужно. Вы можете перетасовывать один и тот же список снова и снова — он будет перетасовываться. @Jarek прав, хотя: я не могу понять, какую задачу это может решить. Вы уверены, что нет лучшего алгоритма для того, что вы делаете, который не включает перетасовку? - person Francis Avila; 05.12.2011
comment
Хм, ты уверен? На моей машине запуск shuffle(L1) перемешивает L1, но только один раз. Повторный запуск shuffle(L1) не перетасовывает список L1. Спасибо за помощь. Алгоритм мог бы быть и получше, но пока я не вижу способа обойти перетасовку. - person drbunsen; 05.12.2011
comment
Я обновил свой ответ, четко продемонстрировав, что shuffle() будет перетасовывать. В самом деле, подумайте об этом логически — откуда shuffle() вообще знает, что он уже перетасовал список? - person Francis Avila; 05.12.2011

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

person Jarek    schedule 05.12.2011
comment
Мой пример — чрезмерное упрощение. На самом деле я генерирую счет для каждого перетасованного списка, и мне нужно перемешивать до тех пор, пока не будет сгенерирован счет выше определенного порога. - person drbunsen; 05.12.2011
comment
@dr.bunsen - Затем просмотрите список, пока не найдете приемлемый результат. - person Buttons840; 05.12.2011
comment
@ Butttons840 Возможно, вы могли бы продемонстрировать то, что описываете? Я перебираю список, чтобы найти приемлемые оценки. Если оценка неприемлема, мне нужно перетасовать до тех пор, пока не будет получена приемлемая оценка. - person drbunsen; 05.12.2011