Shuffling a list of objects

后端 未结 23 1686
眼角桃花
眼角桃花 2020-11-22 00:29

I have a list of objects and I want to shuffle them. I thought I could use the random.shuffle method, but this seems to fail when the list is of objects. Is the

相关标签:
23条回答
  • 2020-11-22 00:50

    If you have multiple lists, you might want to define the permutation (the way you shuffle the list / rearrange the items in the list) first and then apply it to all lists:

    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

    If your lists are numpy arrays, it is simpler:

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

    mpu

    I've created the small utility package mpu which has the consistent_shuffle function:

    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)
    

    Note that mpu.consistent_shuffle takes an arbitrary number of arguments. So you can also shuffle three or more lists with it.

    0 讨论(0)
  • 2020-11-22 00:51

    'print func(foo)' will print the return value of 'func' when called with 'foo'. 'shuffle' however has None as its return type, as the list will be modified in place, hence it prints nothing. Workaround:

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

    If you're more into functional programming style you might want to make the following wrapper function:

    def myshuffle(ls):
        random.shuffle(ls)
        return ls
    
    0 讨论(0)
  • 2020-11-22 00:51

    Plan: Write out the shuffle without relying on a library to do the heavy lifting. Example: Go through the list from the beginning starting with element 0; find a new random position for it, say 6, put 0’s value in 6 and 6’s value in 0. Move on to element 1 and repeat this process, and so on through the rest of the list

    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
    
    0 讨论(0)
  • 2020-11-22 00:52
    from random import random
    my_list = range(10)
    shuffled_list = sorted(my_list, key=lambda x: random())
    

    This alternative may be useful for some applications where you want to swap the ordering function.

    0 讨论(0)
  • 2020-11-22 00:52

    In some cases when using numpy arrays, using random.shuffle created duplicate data in the array.

    An alternative is to use numpy.random.shuffle. If you're working with numpy already, this is the preferred method over the generic random.shuffle.

    numpy.random.shuffle

    Example

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

    Using 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]])
    

    Using 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]])
    
    0 讨论(0)
  • 2020-11-22 00:53

    You can go for this:

    >>> 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']
    

    if you want to go back to two lists, you then split this long list into two.

    0 讨论(0)
提交回复
热议问题