Перетасовка списка объектов
У меня есть список объектов, и я хочу перетасовать их. Я думал, что мог бы использовать метод random.shuffle
, но, похоже, это не сработает, когда список объектов. Есть ли способ перетасовки объектов или другой способ обойти это?
import random
class A:
foo = "bar"
a1 = a()
a2 = a()
b = [a1, a2]
print(random.shuffle(b))
Это не удастся.
Ответы
Ответ 1
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.
Ответ 2
Как вы поняли, на месте было перетасовка. У меня также часто возникает проблема, и я часто забываю, как скопировать список. Использование 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
Ответ 3
Мне потребовалось некоторое время, чтобы получить это тоже. Но документация по shuffle очень понятна:
shuffle list x in place; return None.
Так что не стоит print(random.shuffle(b))
. Вместо этого сделайте random.shuffle(b)
, а затем print(b)
.
Ответ 4
#!/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]
Ответ 5
Если вы уже используете numpy (очень популярны для научных и финансовых приложений), вы можете сохранить импорт.
import numpy as np
np.random.shuffle(b)
print(b)
http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
Ответ 6
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']
Он отлично работает для меня. Не забудьте установить случайный метод.
Ответ 7
Если у вас есть несколько списков, вы можете сначала определить перестановку (способ перестановки списка/перестановки элементов в списке), а затем применить его ко всем спискам:
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
принимает произвольное количество аргументов. Таким образом, вы также можете перемешать три или более списков с ним.
Ответ 8
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())
Эта альтернатива может быть полезна для некоторых приложений, где вы хотите поменять функцию упорядочения.
Ответ 9
В некоторых случаях при использовании пустых массивов использование 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]])
Ответ 10
'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
Ответ 11
Для однострочных random.sample(list_to_be_shuffled, length_of_the_list)
используйте random.sample(list_to_be_shuffled, length_of_the_list)
с примером:
import random
random.sample(list(range(10)), 10)
выходы: [2, 9, 7, 8, 3, 0, 4, 1, 6, 5]
Ответ 12
Можно определить функцию, называемую shuffled
(в том же смысле sort
vs sorted
)
def shuffled(x):
import random
y = x[:]
random.shuffle(y)
return y
x = shuffled([1, 2, 3, 4])
print x
Ответ 13
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
a3 = a()
a4 = a()
b = [a1,a2,a3,a4]
random.shuffle(b)
print(b)
shuffle
на месте, поэтому не печатайте результат, который есть None
, а список.
Ответ 14
Вы можете пойти на это:
>>> A = ['r','a','n','d','o','m']
>>> B = [1,2,3,4,5,6]
>>> import random
>>> random.sample(A+B, len(A+B))
[3, 'r', 4, 'n', 6, 5, 'm', 2, 1, 'a', 'o', 'd']
если вы хотите вернуться к двум спискам, вы разделите этот длинный список на два.
Ответ 15
вы можете создать функцию, которая принимает список как параметр и возвращает перетасованную версию списка:
from random import *
def listshuffler(inputlist):
for i in range(len(inputlist)):
swap = randint(0,len(inputlist)-1)
temp = inputlist[swap]
inputlist[swap] = inputlist[i]
inputlist[i] = temp
return inputlist
Ответ 16
""" to shuffle random, set random= True """
def shuffle(x,random=False):
shuffled = []
ma = x
if random == True:
rando = [ma[i] for i in np.random.randint(0,len(ma),len(ma))]
return rando
if random == False:
for i in range(len(ma)):
ave = len(ma)//3
if i < ave:
shuffled.append(ma[i+ave])
else:
shuffled.append(ma[i-ave])
return shuffled
Ответ 17
вы можете либо использовать тасование, либо образец. оба из которых исходят из случайного модуля.
import random
def shuffle(arr1):
n=len(arr1)
b=random.sample(arr1,n)
return b
ИЛИ ЖЕ
import random
def shuffle(arr1):
random.shuffle(arr1)
return arr1
Ответ 18
Убедитесь, что вы не назовете ваш исходный файл random.py и что в вашем рабочем каталоге, называемом random.pyc, нет файла, который может заставить вашу программу попробовать и импортировать локальный файл random.py вместо случайный модуль pythons.
Ответ 19
def shuffle(_list):
if not _list == []:
import random
list2 = []
while _list != []:
card = random.choice(_list)
_list.remove(card)
list2.append(card)
while list2 != []:
card1 = list2[0]
list2.remove(card1)
_list.append(card1)
return _list
Ответ 20
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
b = [a1.foo,a2.foo]
random.shuffle(b)
Ответ 21
Процесс перетасовки "заменяется" , поэтому появление каждого элемента может измениться! По крайней мере, когда элементы в вашем списке также перечислены.
например.
ml = [[0], [1]] * 10
После
random.shuffle(ml)
Число [0] может быть 9 или 8, но не точно 10.
Ответ 22
План. Выполните перетасовку, не полагаясь на библиотеку, чтобы сделать тяжелый подъем. Пример: перейдите в список с начала, начиная с элемента 0; найдите новую случайную позицию для него, скажем, 6, положите значение 0s в значение 6 и 6s в 0. Перейдите к элементу 1 и повторите этот процесс и так далее через оставшуюся часть списка
import random
iteration = random.randint(2, 100)
temp_var = 0
while iteration > 0:
for i in range(1, len(my_list)): # have to use range with len()
for j in range(1, len(my_list) - i):
# Using temp_var as my place holder so I don't lose values
temp_var = my_list[i]
my_list[i] = my_list[j]
my_list[j] = temp_var
iteration -= 1
Ответ 23
Он отлично работает. Я пытаюсь здесь с функциями в виде объектов списка:
from random import shuffle
def foo1():
print "foo1",
def foo2():
print "foo2",
def foo3():
print "foo3",
A=[foo1,foo2,foo3]
for x in A:
x()
print "\r"
shuffle(A)
for y in A:
y()
Он печатает:
foo1 foo2 foo3
foo2 foo3 foo1
(foos в последней строке имеют случайный порядок)