Reputation:
I'm trying to randomly select items from a list and add them to another list.
The list of elements I'm choosing from looks like this:
data=[2,3,4,7,8,12,17,24,27,33,35,36,37,38,40,43,44,50,51,54]
I want to randomly take an element from this list and add it to one of four lists until each list has the same number of elements.
lists=[[1,'x','x','x','x','x'],[3,'x','x','x','x','x'],[5,'x','x','x','x','x'],[7,'x','x','x','x','x']]
I have tried using random.choice but this gives me duplicates:
def fill_lists(data):
for list in lists:
for n,i in enumerate(list):
if i=='x':
list[n]= random.choice(data)
I want my function to return a list that contains 4 lists each containing a random sample of the data list with no duplicates. I also want the first element of each list to be a value that I have already placed into the list.
Upvotes: 3
Views: 3127
Reputation: 9746
This is a dynamic function that returns a list of list where each list starts with a specified value. The amount of nested lists is determined by the amount of starting_values.
import random
def get_random_list(element_list, starting_values, size_per_group):
num_of_groups = len(starting_values)
size_per_group -= 1
total_elements = num_of_groups * size_per_group
random_data = random.sample(element_list, total_elements)
return [[starting_values[x]] + random_data[x * size_per_group:(x + 1) * size_per_group] for x in range(num_of_groups)]
data = [2, 3, 4, 7, 8, 12, 17, 24, 27, 33, 35, 36, 37, 38, 40, 43, 44, 50, 51, 54]
print(get_random_list(data, starting_values=[1, 2, 3, 4, 5, 6], size_per_group=2))
# OUTPUT: [[1, 36], [2, 54], [3, 17], [4, 7], [5, 35], [6, 33]]
print(get_random_list(data, starting_values=[9, 3, 5], size_per_group=6))
# OUTPUT: [[9, 54, 2, 7, 38, 24], [3, 35, 8, 37, 40, 17], [5, 44, 4, 27, 50, 3]]
It works for Python2.x and Python3.x but for Python2.x you should change range()
to xrange()
for better use of memory.
Upvotes: 0
Reputation: 812
import random
data=[2,3,4,7,8,12,17,24,27,33,35,36,37,38,40,43,44,50,51,54]
random.shuffle(data)
lists = [data[i:i+len(data)/4] for i in range(0, len(data), len(data)/4)]
print(lists)
Randomly pulling from your initial list will have the same effect as shuffling then pulling in order. Splitting into sublists can then be done. If you need the sublists sorted, just map sort over the list afterwards.
You can change the number of groups by altering the divisor of len(data)/4
Edit: I missed this part of your question:
heads = [1,3,5,7]
[q.insert(0,p) for p,q in zip(heads,lists)]
Upvotes: 3
Reputation: 1753
You could try this, modifying the ranges inside the d
function to tune to the number elements you want.
import random
def f(data):
val = random.choice(data)
ix = data.index(val)
data.pop(ix)
return val, data
def d(data):
topholder = []
m = len(data)/4
for i in range(4):
holder = []
for n in range(m):
holder.append(f(data)[0])
topholder.append(holder)
return topholder
d(data)
This will always give you 4 lists of randomly sampled values without duplication.
Upvotes: 0
Reputation: 67497
another shuffle based but ensuring the all sub lists have the same size in case number of elements is not divisible to number of lists (try 7 for example).
from random import shuffle
def split(data, n):
size=int(len(data)/n);
for i in range(0, n*size, size):
yield data[i:i+size]
data=[2,3,4,7,8,12,17,24,27,33,35,36,37,38,40,43,44,50,51,54]
shuffle(data)
list(split(data, 5))
Upvotes: 0
Reputation: 1838
You can use random.sample
:
data=[2,3,4,7,8,12,17,24,27,33,35,36,37,38,40,43,44,50,51,54]
random.sample(data, 5)
# [27, 12, 33, 24, 17]
To get a nested list of it, use a list comprehension
[random.sample(data, 5) for _ in range(5)]
# [[40, 35, 24, 54, 17],
# [17, 54, 35, 43, 37],
# [40, 4, 43, 33, 44],
# [51, 37, 35, 33, 8],
# [54, 4, 44, 27, 50]]
Edit: The above won't give you unique values; you should accept the above answer for the unique values. I interpreted the question wrong!
Upvotes: 1