Перетасовка списка объектов
у меня есть список объектов в Python и я хочу, чтобы перетасовать их. Я думал, что смогу использовать random.shuffle метод, но это, кажется, ошибка, когда список объектов. Есть ли способ перетасовки объекта или другой способ обойти это?
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
b = [a1,a2]
print random.shuffle(b)
это не удастся.
23 ответов:
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обратите внимание, что шафл работает на месте, и возвращает None.
как вы узнали, перетасовка на месте была проблемой. У меня также часто возникают проблемы, и часто кажется, что я тоже забываю, как скопировать список. Используя
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
мне тоже потребовалось некоторое время, чтобы понять это. Но документация для shuffle очень ясна:
перемешать список x на месте; возвращает ни один.
Так что вы не должны
print random.shuffle(b). Вместо этого сделайтеrandom.shuffle(b)а тоprint b.
#!/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]
>>> import random >>> a = ['hi','world','cat','dog'] >>> random.shuffle(a,random.random) >>> a ['hi', 'cat', 'dog', 'world']он отлично работает для меня. Убедитесь в том, чтобы установить случайный способ.
Если вы уже используете numpy (очень популярный для научных и финансовых приложений), вы можете сохранить себе импорт.
import numpy as np np.random.shuffle(b) print(b)http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
если у вас есть несколько списков, вы можете сначала определить перестановку (способ перетасовки списка / перестановки элементов в списке), а затем применить ее ко всем спискам:
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
если ваши списки являются массивами numpy, это проще:
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принимает произвольное количество аргументов. Таким образом, вы также можете перетасовать три или более списков с ним.
from random import random my_list = range(10) shuffled_list = sorted(my_list, key=lambda x: random())Это может быть полезно для некоторых приложений, где вы хотите поменять функцию заказ.
' print func (foo)' будет печатать возвращаемое значение 'func' при вызове с помощью 'foo'. однако "shuffle" не имеет никакого возвращаемого типа, так как список будет изменен на месте, поэтому он ничего не печатает. Обходной путь:
# shuffle the list in place random.shuffle(b) # print it print(b)Если вы больше в функциональном стиле программирования вы можете сделать следующую функцию оболочки:
def myshuffle(ls): random.shuffle(ls) return ls
в некоторых случаях при использовании массивов 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]])
можно определить функцию
shuffled(в смыслеsortvssorted)def shuffled(x): import random y = x[:] random.shuffle(y) return y x = shuffled([1, 2, 3, 4]) print x
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, но список.
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
убедитесь, что вы не называете свой исходный файл random.py, и что в вашем рабочем каталоге нет файла под названием random.пик.. либо может привести к тому, что ваша программа попытается импортировать ваш локальный random.py файл вместо модуля pythons random.
вы можете пойти на это:
>>> 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']Если вы хотите вернуться к двум спискам, то разделите этот длинный список на два.
вы можете построить функцию, которая принимает список в качестве параметра и возвращает перемешанную версию списка:
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
""" 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
вы можете использовать пустую или образца . оба из которых исходят из случайного модуля.
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
для острот, используйте
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]
процесс перетасовки "с заменой", так что появление каждого элемента может меняться! По крайней мере, когда, когда элементы в вашем списке также список.
например,
ml = [[0], [1]] * 10после
random.shuffle(ml)число [0] может быть 9 или 8, но не точно 10.
план: выпишите перетасовку, не полагаясь на библиотеку, чтобы сделать тяжелую работу. Пример: пройдитесь по списку с самого начала, начиная с элемента 0; найдите для него новую случайную позицию, скажем 6, Поместите значение 0 в 6 и значение 6 в 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
Он работает нормально. Я пытаюсь это здесь с функциями в качестве объектов списка:
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 в последней строке имеют случайный порядок)
Comments