【问题标题】:Comparing objects based on sets as attributes | TypeError: Unhashable type基于集合作为属性比较对象 | TypeError:不可散列的类型
【发布时间】:2016-12-26 12:08:43
【问题描述】:

python 中真正让我害怕的是这个错误:TypeError: unhashable type

理想情况下,我希望有一个数据结构,我只使用集合而不是列表,这样我就可以像这样使用集合运算符:

a = {({1,2}, 'alpha'), ({2,3}, 'beta')}
b = {({1,2}, 'alpha')}

c = a - b # c = {({2,3}, 'beta')}

我什至无法创建包含集合的集合,因为我得到了TypeError: unhashable type: set

所以我尝试使用列表而不是集合。这样我至少可以为a和b分配值。但是再次使用 set 方法从另一个集合中减去一个集合会导致相同的错误:

a = [({1,2}, 'alpha'), ({2,3}, 'beta')]
b = [({1,2}, 'alpha')]

c = list(set(a) - set(b)) # c = [({2,3}, 'beta')]

我用字典而不是列表尝试过,同样的错误。

问题:我如何比较两个包含某处包含集合的元素的字符串?

或者我认为根本错误/“不是pythonic”并且错误植根于数据结构本身?

感谢您的帮助!

莫夫

【问题讨论】:

  • 抱歉打错了!
  • 好吧,现在正如@Slam 所建议的那样,将{1, 2} 替换为frozenset([1, 2]) 就可以了。

标签: python python-3.x


【解决方案1】:

您唯一能做的就是将frozenset 用于内部数据(或者如果它来自外部世界,则将集合转换为frozensets),因为它正是为此创建的。

标准库中的任何可变数据结构都不能进行散列处理(可能大多数实现都不应该),原因很简单。如果您考虑如何在 set/list 上实现散列,您会很快得到它;)

【讨论】:

  • '没有可变的数据结构可以被散列'是不正确的。你可以在任何类中实现__hash__(self)(但你可能不应该)。
【解决方案2】:

您只能将不可变(或至少hashable)数据放入set(或作为字典的键)。 set 本身不是一成不变的;但是frozenset 是。

这里有一个类似的问题:Why aren't Python sets hashable?

a = {(frozenset((1, 2)), 'alpha'), (frozenset((2, 3)), 'beta')}
b = {(frozenset((1, 2)), 'alpha')}

c = a - b
print(c)  # -> {(frozenset({2, 3}), 'beta')}

这正是你想要的。

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 2018-09-02
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多