2

Let's say I have an array of strings which take the format of dates in a YYYYMMDD format. For example:

 masterlist = ['20190701', '20190702', ... '20190731'] 

Let's say I want to create a new series of 3 lists with lengths of x, y, and z. For this example, we can simply say x = 20, y = 10, and z = 1. The format is such that I would like to loop through all of the elements in masterlist to set as z. From here, I want to take 20 random dates which do not contain the date in z and assign those to x. Lastly, those dates not in x or z, will be left for y. In other words, no list should have the same date.

For example:

z = ['20190701']
x = ['20190702', ... , '20190721']
y = ['20190722', ... , '20190731']

And another:

z = ['20190702']
x = ['20190701', '20190703', ..., '20190720']
y = ['20190722', ... , '20190731']

It does not matter the order or random mixing between x and/or y, so long as the lists are mutually exclusive and collectively exhaustive.

What is the simplest way to achieve this?

1
  • 1
    sounds like you might need random.sample Commented Jan 2, 2020 at 21:13

4 Answers 4

3

You can do this using sets (lets say my z=1, x=2, y=1 and masterlist=5)

import random
masterlist = ['20190701', '20190702', '20190703', '20190704', '20190705']
z = random.sample(masterlist, 1)
x = random.sample((set(masterlist) - set(z)), 2)
y = random.sample(((set(masterlist) - set(x)) - set(z)), 1)
# z ['20190702']
# x ['20190701', '20190705']
# y ['20190704']

This is finding the difference between sets (where it will return the values in the first set that are not in the second set), and the number at the end is the sample size.

Sign up to request clarification or add additional context in comments.

3 Comments

So if I wanted to make Z hardcoded to the first value in masterlist (e.g., z = masterlist[0]) and continue with the rest of the code, it will be included in x. Why is this?
Because masterlist[0] is a string, not a list. When you call set on a string, it actually breaks the set down into individual characters in the string, so the set would be something like {'0', '9', '7', '2', '1'}. One of the best trouble shooting methods is the print function :P. I always print after I write a block of code to make sure I am getting the result I should.
random.sample(masterlist, 1) is still actually returning a list of length 1.
2

You can do this by creating a dictionary of "rules" you want to set up the dividing of the master list , this way you earn dynamism and control on the way you divide the master list:

import random
import pprint as pp
master_list = range(0,31,1) # this is your dates list from 2019.07.01 to 2019.07.31

divided = { # also set up for applying rules of dividing the master list
    1 : 20,
    2 : 10,
    3 : 1
}


taken = []
for k,v in divided.items():
    divided[k] = random.sample([element for element in master_list if element not in taken],v)
    for t in divided[k]: taken.append(t)

pp.pprint(divided)

OUTPUT::

{1: [26, 25, 8, 22, 17, 19, 13, 7, 14, 0, 27, 18, 30, 5, 2, 6, 20, 1, 11, 9],
 2: [15, 21, 23, 28, 4, 16, 10, 24, 3, 12],
 3: [29]
}

You could just add another key:value to the divided dictionary to set another "divider" of course.

Comments

1

You could randomly shuffle the list and then slice it (substitute the lengths you want):

import random

masterlist = ['20190701', '20190702', ... '20190731']
newlist = [a for a in masterlist]
random.shuffle(newlist)
x = newlist[:20]
y = newlist[20:30]
z = newlist[-1]

Comments

0

You can just shuffle the masterlist, and then put the elements in the lists while ensuring they are not in the others.

I made a function that makes a list of a certain length while checking that the elements are not in a certain set. I assumed also that within the three lists you can have duplicates, but not between the lists.

def makeListWithConstraint(masterlist, newlength, constraintSet=set()):
    i = 0
    l = []
    while (len(l) < newlength): # keep going until list has desired length
        if masterlist[i] not in constraintSet:
            l.append(masterlist.pop(i))  # pop also deletes items from the masterlist
        else:
            i += 1
    return l

Then you would use the function as follows for your example:

# shuffle first to ensure random
random.shuffle(masterlist)

# make constrained lists
z_list = makeListWithConstraint(masterlist, x)
x_list = makeListWithConstraint(masterlist, x, set(z_list))
y_list = makeListWithConstraint(masterlist, y, set(z_list + x_list))

1 Comment

I saw d-kennetz solution, and random.sample() is a good alternative for my custom function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.