【问题标题】:Making a set of sets returns unhashable type: 'list'制作一组集合返回不可散列的类型:'list'
【发布时间】:2019-03-30 01:50:10
【问题描述】:
S=set()
for i in range(1,100):
    for j in range(1,100):
        for k in range(1,100):
            if i**2+j**2==k**2:
                S.add(([i,j,k]))
print S

错误是

TypeError                                 Traceback (most recent call last)
<ipython-input-45-606e3083d711> in <module>()
      4         for k in range(1,100):
      5             if i**2+j**2==k**2:
----> 6                 S.add(([i,j,k]))
      7 print S

TypeError: unhashable type: 'list'

我只想得到所有不同的毕达哥拉斯三元组 [对我来说 (3,4,5)=(4,3,5)]。这就是为什么我用集合来做这件事,但由于某种原因,我无法将集合附加到我的原始集合 S...

【问题讨论】:

  • 您搜索过错误吗?你不能散列列表,因为它们是可变的。
  • 您只能将不可变类型添加到 tuplefrozenset 之类的集合中。
  • ji循环到100kj循环到100,这样可以避免删除重复项。
  • 只是将元组添加到内置集合中无论如何都不会为您做到这一点,因为在 Python 中,(3, 4, 5) != (4, 3, 5)。按照佩奇大卫所说的去做。 :)

标签: python list set append


【解决方案1】:

不要创建一组列表,只需对列表进行排序并转换为元组(以避免重复):

S=set()
for i in range(1,100):
    for j in range(1,100):
        for k in range(1,100):
            if i**2+j**2==k**2:
                # Notice I've changed squared brackets to round brackets for tuples, and sorted the list, so that duplicates are eliminated.
                S.add(tuple(sorted([i,j,k])))
print(S)

`

我假设现在运行时效率并不重要。

【讨论】:

    【解决方案2】:

    set的元素需要是hashable的,即不可变的,用tuple代替list。 或者你可以使用frozenset。

    对于“get all the distinct Pythagorean triples [for me (3,4,5)=(4,3,5)].”,您可以将i 限制为较小的,j 限制为较大的,示例代码如下:

    S = set()
    for i in range(1, 100):
        # include i to support i=j case
        for j in range(i, 100):
            for k in range(1, 100):
                if i ** 2 + j ** 2 == k ** 2:
                    S.add((i, j, k))
    

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 2013-01-23
      • 2017-06-21
      • 2017-12-27
      • 2011-07-29
      相关资源
      最近更新 更多