Given this python code snippet:
import numpy as np
rng = np.random.default_rng(42)
class Agent:
def __init__(self, id):
self.id = id
self.friends = set()
def __repr__(self):
return str(self.id)
group_list = list()
for i in range(100):
new_obj = Agent(i)
group_list.append(new_obj)
for person in group_list:
pool = rng.choice([p for p in group_list if p != person], 6)
for p in pool:
person.friends.add(p)
def set_to_list_ordered(a_set):
return sorted(list(a_set), key=lambda x: x.id)
print("This will change: ")
print(rng.choice(list(group_list[0].friends), 2))
print("This will not change: ")
print(rng.choice(set_to_list_ordered(group_list[0].friends), 2))
The purpose of this code is to perform a random extraction of 2 elements from a set. The problem is that the np.random.choiche function does not accept a set, so you have to turn it into a list. But, doing this, the order of the elements is random and given the same seed, the result of the random extraction is not replicable. In this case I implemented a function that sorts the elements, but it is costly.
You will rightly say, use a list instead of a set. To this I reply that sets fit perfectly the use I need. For example, this structure allows the Agent.friends attribute to have no duplicate elements.
So, my question is, what is the most convenient method, other than the function I implemented, to use sets and have the random extraction from a set be deterministic? Is it better to use lists instead of sets? Is there any way to make the transformation deterministic?
Thanks in advance.
EDIT: Some observe that internally the transformation from set to list is consistent. My objective is for this transformation to be consistent externally as well. So that by running the same script numerous times, the extraction of the default_rng instance is the same.
Solved by overriding the hash() method. Source: https://www.youtube.com/watch?v=C4Kc8xzcA68
import numpy as np
rng = np.random.default_rng(42)
class Agent:
def __init__(self, id):
self.id = id
self.friends = set()
def __repr__(self):
return str(self.id)
def __hash__(self):
return self.id
group_list = list()
for i in range(100):
new_obj = Agent(i)
group_list.append(new_obj)
for person in group_list:
pool = rng.choice([p for p in group_list if p != person], 6)
for p in pool:
person.friends.add(p)
def set_to_list_ordered(a_set):
return sorted(list(a_set), key=lambda x: x.id)
print("This will change: ")
print(rng.choice(list(group_list[0].friends), 2))
print("This will not change: ")
print(rng.choice(set_to_list_ordered(group_list[0].friends), 2))