I am simulating a draw of names from a hat. I have two lists.
List "a" with names and "b" indicating team.
a = ["A", "B", "C", "D", "E", "F"]
b = [ 1, 1, 2, 2, 3, 3 ]
I use random.sample(a, 6)
to randomly draw.
You are not allowed to draw yourself or your teammate.
E.g. "A" is not allowed to draw "A" or "B", "D" is not allowed to draw "C" or "D".
What is the best approach to compare such lists?
Edit:
So the idea is, that e.g., "A" and "B" are in the same group. If random.sample(a, 6)
array has "A" or "B" in index 0 or 1 - > it's a failure. If "C" or "D" is in position 2 or 3 -> failure.
I am aiming to get just TRUE or FALSE.
CodePudding user response:
a = ["A", "B", "C", "D", "E", "F"]
b = [ 1, 1, 2, 2, 3, 3 ]
d={}
for i in range(len(a)):
d[a[i]]=b[i]
from random import shuffle
def g():
shuffle(a)
r=a[0]
i=d[r]
for v in a[1:]:
if d[v]!=i:
r =v
return r
print(g())
CodePudding user response:
OK, taking a stab at your question. I think you may really be trying to figure out how to generate a valid sample respecting the rule that a player cannot choose themselves or their teammate, and you figure "let's create a sample and test it against that rule; try again until a good one is found". That approach can work, but it's very inefficient, because you might have to draw a whole bunch of times before you get a valid sample. It's best to change the draw process itself to only let each player pick among players they're allowed to pick from instead.
But...
Answering your question as asked, you can create a dict when you store each player's team numbers, and then you can ask for each value, "Is the team of the player chosen the same as the team of the player doing the choosing?"
Hard coded, this dict would look like this:
team_dict = { "A": 1, "B": 1, "C": 2, "D": 2, "E": 3, "F": 3 }
We can use a dict comprehension and the builtin zip()
function in Python to create this dict in one line from you player and team lists:
team_dict = { player: team for player, team in zip(a, b) }
Now, once you have your sample, let's call it s
, we're going to use zip again to see if the original player in the position and the sampled player are in the same team:
def validate_sample(list_of_players, sample):
# Return false as soon as one violation is found
for chooser, chooser in zip(list_of_players, sample):
if team_dict[chooser] == team_dict[choosee]:
return False
# If we get this far, there were no violations
return True
s = random.sample(a, 6)
OK = validate_sample(a, s)
Important language features highlighted:
zip()
lets you iterate through multiple lists in parallel. In other languages, you would loop over indices, and subscript each list. In Python, the preferred way to do this is viazip()
. Warning: if one list of shorter than the other(s), zip will stop at the end of the shortest list and just silently ignore the rest of the other lists.- Comprehensions let you construct lists, sets, dict or even iterators in a very compact way. If you're learning Python and you're not familiar with comprehensions, Google "Python comprehensions" and read up on them. They're confusing at first, but they're a very powerful feature of the language for building these data structures.