【问题标题】:Confused with Python sets adding same object twice对 Python 集添加相同对象两次感到困惑
【发布时间】:2018-02-28 10:27:37
【问题描述】:

如果我将一个整数添加到 Python 集合对象两次,Python 只会添加一次。

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

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

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>}

我不太确定我在这里做了什么。我是否正确地认为如果协程对象不可散列,它就不会被添加到集合中?所以它是可哈希的,对吧?

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

【问题讨论】:

  • add 方法实际上返回 None。
  • 你创建了两个具有不同 foo 协程函数 id 的 func 实例......你到底想要实现什么
  • 每次调用同步函数时,你只是得到一个不同的协程对象。在最后一行的那些对象的表示中可以清楚地看到。

标签: python set hashable


【解决方案1】:

集合使用散列来比较对象,因此如果两个对象的__ 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}

如你所见,两个对象的哈希值不同,这都依赖于内部协程 __hash __ 方法的实现

添加:而且 obj1.__ eq__(obj2) 也应该是 True

【讨论】:

  • 不仅如此,即使__hash__() 为两个对象返回相同的值,如果它们不相等,它们仍然会被独立添加(使用__eq__(other))。
  • 是的,您是对的,感谢您完成问题。
【解决方案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>]

【讨论】:

    猜你喜欢
    • 2014-11-28
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多