2017-09-27 92 views

Odpowiedz

7

prosty sposób, aby to zrobić jest za pomocą następujących trzy kroki:

  1. tworzenie bloków (lista 2d);
  2. potasuj tę listę; i
  3. scalić te listy ponownie.

Więc:

import random 

# Import data 
data = [1,2,3,4,5,6] 
blocksize = 2 

# Create blocks 
blocks = [data[i:i+blocksize] for i in range(0,len(data),blocksize)] 
# shuffle the blocks 
random.shuffle(blocks) 
# concatenate the shuffled blocks 
data[:] = [b for bs in blocks for b in bs] 

Jeśli nie chcesz, aby zapisać dane z powrotem w data, można po prostu użyć:

data = [b for bs in blocks for b in bs] 

Dla tych danych uzyskałem:

>>> data 
[3, 4, 1, 2, 5, 6] 

drugi raz:

>>> data 
[5, 6, 1, 2, 3, 4] 
+0

Miło, ale czuję, że musi być jeszcze bardziej elegancki sposób na zrobienie tego w 'numpy' ... –

+2

@Chris_Rands [tam jest] (https://stackoverflow.com/a/32492169/1040092) :) – Wondercricket

+1

Dzięki dla odpowiedzi, która jest ogólnym sposobem mieszania danych w porcjach. – jmir

3

można użyć modułu random i wywołać funkcję random.shuffle() - będzie mieszał każdy element na liście, więc przełamać swoją listę do podlist przed tasowanie

import random, itertools 

mylist = [1, 2, 3, 4, 5, 6] 
blocks = [mylist[x:x+2] for x in range(0, len(mylist), 2)] 
random.shuffle(blocks) 
list(itertools.chain.from_iterable(blocks)) 
>> [3, 4, 1, 2, 5, 6] 
+2

Wierzę, że OP chce zgrupować dane (stąd * bloki *), dzięki czemu sąsiednie pary pozostają w sąsiedztwie po przetasowaniu. – SwiftsNamesake

1

Brak builtins, ale można napisać mały pomocnika to zrobić dla Ciebie:

1- tworzyć bloki
2- Shuffle im
3- spłaszczyć bloki i zwrócić otrzymaną przetasowana sekwencja. Próbka

import random 

    def shuffle_by_blocks(seq, blocksize): 
     blocks = [seq[idx*blocksize: (idx+1)*blocksize] for idx in range(len(seq)//blocksize)] 
     random.shuffle(blocks) 
     return [elt for block in blocks for elt in block ] 

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

wyjściowa:

[1, 2, 5, 6, 3, 4] 
2

z maksymalnym wykorzystaniem standardowych metod:

>>> import random, itertools 
>>> a 
[1, 2, 3, 4, 5, 6] 

# group elements by 2 
>>> grouped = list(zip(*[iter(a)]*2)) 
>>> grouped 
[(1, 2), (3, 4), (5, 6)] 

# shuffle groups 
>>> random.shuffle(grouped) 
>>> grouped 
[(3, 4), (1, 2), (5, 6)] 

# flatten groups to list 
>>> list(itertools.chain.from_iterable(grouped)) 
[3, 4, 1, 2, 5, 6] 
2

Prosty sposób

import random 
data = [1,2,3,4,5,6] 
temp = range(len(data)/2) 
random.shuffle(temp) 
data_c = data[:] 
for i, j in enumerate(temp): 
    if not i == j: 
     data_c[i*2],data_c[(i*2)+1] = data[j*2],data[(j*2)+1] 
print(data_c) 

Wyjście

[1, 2, 5, 6, 3, 4] 
+1

Dobrze, przetasowuje indeksy bloków. – VPfB

0

Ktoś poprosił o rozwiązanie za pomocą numpy:

>>> import numpy as np 
>>> a = np.array([1, 2, 3, 4, 5, 6]) 
>>> np.random.shuffle(a.reshape((-1, 2))) 
>>> a 
array([5, 6, 3, 4, 1, 2]) 

Ten tasuje przekształcony widok w miejscu, ale zachowuje swoje oryginalne wymiary, więc nie ma potrzeby, aby przekształcić z powrotem.