I am trying to create random pairs without replacement of fruits which are all in one list.
The problem is that this list may contain an even number of fruits or odd. If the number of fruits is even then I want to create pairs of two by dividing the number of fruits/2. I.e. If I have 4 fruits, I can create a total of 2 pairs of 2 fruits that are randomly matched.
However, when it comes to an odd number of fruits, it is more complicated. For example, I have 5 fruits and it should create 1 pair of 2 and 1 pair of 3 randomly matched fruits. So, in the odd case there will be pairs of two and 1 pair of three fruits. The requirement is that when creating the pair of 3, it should not take any of the fruits which were used in the even pair(s). I am not sure how to exclude those when creating the odd pair.
This is my code:
import numpy as np
x = ['banana','apple','pear','cherry','blueberry']
fruit_count=len(x)
if fruit_count%2==0:
print('even')
pairs=np.random.choice(x, size=(int(fruit_count/2), 2), replace=False)
print(pairs)
else:
print('odd')
pairs=np.random.choice(x, size=(int((fruit_count/2)-1.5), 2), replace=False)
pairs_odd=np.random.choice(x, size=(int(fruit_count/2)-1, 3), replace=False)
print(pairs_odd)
print(pairs)
The output is showing the problem of having the uneven pair take values from the even pairs. The desired values of the odd pair should be: ['pear','cherry','blueberry']. How do I fix that?
OUTPUT
odd
['cherry' 'banana' 'apple']
['banana' 'apple']
CodePudding user response:
You can use the pairs_odd and create a list found in x items but not found in pairs_odd.
print([item for item in x if item not in pairs_odd[0]])
Result:
odd
['pear' 'cherry' 'banana']
['apple', 'blueberry']
CodePudding user response:
Draw one less pair if the list length is odd. This will leave three elements instead of one element - which are then, by definition, the leftover size-three "pair".
pairs=np.random.choice(x, size=(fruit_count // 2 - 1, 2), replace=False)
You can quickly remove the fruits already in size-two pairs by using set operations.
pair_size_three = list(set(x) - set.union(*(set(pair) for pair in pairs)))