Перемешивание списка объектов - PullRequest
672 голосов
/ 10 июня 2009

У меня есть список объектов в Python, и я хочу перетасовать их. Я думал, что мог бы использовать метод random.shuffle, но это, кажется, терпит неудачу, когда список объектов. Есть ли способ перетасовки объекта или другой способ обойти это?

import random

class a:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1,a2]

print random.shuffle(b)

Это не удастся.

Ответы [ 23 ]

1110 голосов
/ 10 июня 2009

random.shuffle должно работать. Вот пример, где объекты являются списками:

from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)

# print x  gives  [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary

Обратите внимание, что shuffle работает вместо и возвращает None.

102 голосов
/ 19 октября 2012

Как вы узнали, проблема была в перестановке на месте. У меня также часто бывают проблемы, и я часто забываю, как копировать список. Использование sample(a, len(a)) является решением, используя len(a) в качестве размера выборки. См. https://docs.python.org/3.6/library/random.html#random.sample для документации Python.

Вот простая версия, использующая random.sample(), которая возвращает перетасованный результат в виде нового списка.

import random

a = range(5)
b = random.sample(a, len(a))
print a, b, "two list same:", a == b
# print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False

# The function sample allows no duplicates.
# Result can be smaller but not larger than the input.
a = range(555)
b = random.sample(a, len(a))
print "no duplicates:", a == list(set(b))

try:
    random.sample(a, len(a) + 1)
except ValueError as e:
    print "Nope!", e

# print: no duplicates: True
# print: Nope! sample larger than population
44 голосов
/ 21 ноября 2014

Мне тоже понадобилось время, чтобы получить это. Но документация по shuffle очень понятна:

список случайных чисел x на месте ; возврат Нет.

Так что вы не должны print random.shuffle(b). Вместо этого сделайте random.shuffle(b), а затем print b.

34 голосов
/ 04 декабря 2010
#!/usr/bin/python3

import random

s=list(range(5))
random.shuffle(s) # << shuffle before print or assignment
print(s)

# print: [2, 4, 1, 3, 0]
26 голосов
/ 28 февраля 2015

Если вы уже используете numpy (очень популярный для научных и финансовых приложений), вы можете сохранить импорт.

import numpy as np    
np.random.shuffle(b)
print(b)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html

22 голосов
/ 10 июня 2009
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']

У меня отлично работает. Обязательно установите случайный метод.

11 голосов
/ 05 февраля 2017

Если у вас есть несколько списков, вы можете сначала определить перестановку (способ перестановки списка / перестановки элементов в списке), а затем применить его ко всем спискам:

import random

perm = list(range(len(list_one)))
random.shuffle(perm)
list_one = [list_one[index] for index in perm]
list_two = [list_two[index] for index in perm]

Numpy / Scipy

Если ваши списки являются массивами, это проще:

import numpy as np

perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]

MPU

Я создал небольшой пакет утилит mpu, который имеет функцию consistent_shuffle:

import mpu

# Necessary if you want consistent results
import random
random.seed(8)

# Define example lists
list_one = [1,2,3]
list_two = ['a', 'b', 'c']

# Call the function
list_one, list_two = mpu.consistent_shuffle(list_one, list_two)

Обратите внимание, что mpu.consistent_shuffle принимает произвольное количество аргументов. Таким образом, вы также можете перемешать три или более списков с ним.

7 голосов
/ 06 мая 2016
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())

Эта альтернатива может быть полезна для некоторых приложений, где вы хотите поменять местами функцию упорядочения.

5 голосов
/ 24 мая 2013

«print func (foo)» выведет возвращаемое значение «func» при вызове с «foo». 'shuffle', однако, имеет None в качестве возвращаемого типа, поскольку список будет изменен на месте, следовательно, он ничего не печатает. Временное решение:

# shuffle the list in place 
random.shuffle(b)

# print it
print(b)

Если вы в большей степени относитесь к стилю функционального программирования, вам может понадобиться следующая функция-обертка:

def myshuffle(ls):
    random.shuffle(ls)
    return ls
5 голосов
/ 19 декабря 2016

В некоторых случаях при использовании пустых массивов при использовании random.shuffle создаются дублированные данные в массиве.

Альтернативой является использование numpy.random.shuffle. Если вы уже работаете с numpy, этот метод предпочтительнее общего random.shuffle.

numpy.random.shuffle

Пример

>>> import numpy as np
>>> import random

Использование random.shuffle:

>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])


>>> random.shuffle(foo)
>>> foo

array([[1, 2, 3],
       [1, 2, 3],
       [4, 5, 6]])

Использование numpy.random.shuffle:

>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])


>>> np.random.shuffle(foo)
>>> foo

array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...