与添加相同对象twi的Python集相混淆

2024-04-25 06:05:41 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我向Python set对象添加两次整数,Python只会添加一次。你知道吗

a = set()
a.add(5)
a.add(5)
print(a)
>> {5}

但是,在我的应用程序中,我正在尝试向集合中添加协同路由,因为我找不到更好的方法来跟踪哪些协同路由已经在event\u循环中。我对以下行为感到惊讶:

async def foo(something):
    await asyncio.sleep(1)
    print(something)

a = set()
coro_obj = foo("hi") 
a.add(coro_obj)
coro_obj = foo("hi") 
a.add(coro_obj)
print(a)
{<coroutine object foo at 0x7f36f8c52888>, <coroutine object foo at 0x7f36f8c52360>}

我不太确定我在这里做了什么。我认为如果协同程序对象不可散列,它就不会被添加到集合中,对吗?所以它是可散列的,对吗?你知道吗

如果它是可散列的,为什么我们会得到两个具有相同方法/参数的不同散列?你知道吗


Tags: 对象方法addobj路由objectfoohi
2条回答

可以使用字典存储函数和参数集。你知道吗

# dict to store functions
foo_dict = {}

# function that adds functions and sets of args to dict
d_add = lambda d, f, args : d[foo].add(args) if f in d else d.update({f: {args}} )

# function that makes a list of coroutine objects from this dict 
d_bake = lambda d:[f(*args) for f, args_list in d.items() for args in args_list]

结果:

d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi", "bye"))
d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi",))

print(foo_dict)
#{<function foo at 0x7fefc0be1268>: {('hi',), ('hi', 'bye')}}

print(d_bake(foo_dict))
#[<coroutine object foo at 0x7fefc0f39f68>, <coroutine object foo at 0x7fefc0bec048>]

集合使用散列来比较对象,因此如果两个对象的__ hash __()方法返回相同的值,则两个对象将被视为相等。在你的例子中,它是这样的:

a = set()
coro_obj = foo("hi") 
a.add(coro_obj.__hash__())
coro_obj = foo("hi") 
a.add(coro_obj.__hash__())
print(a)
{-9223363267847141772, 8769007586508}

正如您所看到的,这两个对象的散列是不同的,这都依赖于内部协同程序散列方法的实现

加法:和obj1.\eq\uuuj(obj2)也应该是真的

相关问题 更多 >