Python,从集合中转换列表会更改顺序。避免这种情况的最佳方法是什么?
Python, Casting a list from a set changes the order. What is the best way to avoid this?
鉴于此 python 代码片段:
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))
此代码的目的是从集合中随机提取 2 个元素。问题是 np.random.choiche 函数不接受集合,所以你必须把它变成一个列表。但是,这样做,元素的顺序是随机的,并且给定相同的种子,随机提取的结果是不可复制的。在这种情况下,我实现了一个对元素进行排序的函数,但是它的成本很高。
您会正确地说,使用列表而不是集合。对此我的回答是套装非常适合我需要的用途。例如,此结构允许 Agent.friends 属性没有重复元素。
所以,我的问题是,除了我实现的函数之外,使用集合并确定从集合中随机提取的最方便的方法是什么?使用列表而不是集合更好吗?有什么方法可以使转换具有确定性吗?
提前致谢。
编辑:
一些人观察到从集合到列表的转换在内部是一致的。我的 objective 是为了使这种转换在外部也保持一致。这样通过运行多次相同的脚本,default_rng实例的提取是相同的。
您可以使用 ordered set.
来自文档:
from ordered_set import OrderedSet
>>>OrderedSet('abracadabra')
OrderedSet(['a', 'b', 'r', 'c', 'd'])
通过覆盖 hash() 方法解决。资料来源: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))
鉴于此 python 代码片段:
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))
此代码的目的是从集合中随机提取 2 个元素。问题是 np.random.choiche 函数不接受集合,所以你必须把它变成一个列表。但是,这样做,元素的顺序是随机的,并且给定相同的种子,随机提取的结果是不可复制的。在这种情况下,我实现了一个对元素进行排序的函数,但是它的成本很高。
您会正确地说,使用列表而不是集合。对此我的回答是套装非常适合我需要的用途。例如,此结构允许 Agent.friends 属性没有重复元素。
所以,我的问题是,除了我实现的函数之外,使用集合并确定从集合中随机提取的最方便的方法是什么?使用列表而不是集合更好吗?有什么方法可以使转换具有确定性吗?
提前致谢。
编辑: 一些人观察到从集合到列表的转换在内部是一致的。我的 objective 是为了使这种转换在外部也保持一致。这样通过运行多次相同的脚本,default_rng实例的提取是相同的。
您可以使用 ordered set.
来自文档:
from ordered_set import OrderedSet
>>>OrderedSet('abracadabra')
OrderedSet(['a', 'b', 'r', 'c', 'd'])
通过覆盖 hash() 方法解决。资料来源: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))