Перетасовка списка объектов



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



import random

class a:
foo = "bar"

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

print random.shuffle(b)


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

719   23  

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.

numpy.случайность.перемешать

пример

>>> 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 (в смысле sort vs sorted)

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
import random
class a:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1.foo,a2.foo]
random.shuffle(b)

для острот, используйте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

    Ничего не найдено.