【问题标题】:Adding the number 1 to a set has no effect将数字 1 添加到集合中没有效果
【发布时间】:2012-05-02 18:53:58
【问题描述】:

我无法将整数 1 添加到现有集合中。在交互式外壳中,这就是我正在做的事情:

>>> st = {'a', True, 'Vanilla'}
>>> st
{'a', True, 'Vanilla'}
>>> st.add(1)
>>> st
{'a', True, 'Vanilla'}   # Here's the problem; there's no 1, but anything else works
>>> st.add(2)
>>> st
{'a', True, 'Vanilla', 2}

这个问题是两个月前发布的,但我相信它被误解了。 我正在使用 Python 3.2.3。

【问题讨论】:

  • 为什么要尝试将真值、字符串和数字存储在一个集合中?你想解决什么问题?

标签: python python-3.x set


【解决方案1】:
>>> 1 == True
True

我相信你的问题是 1True 是相同的值,所以 1 是“已经在集合中”。

>>> st
{'a', True, 'Vanilla'}
>>> 1 in st
True

在数学运算中True 本身被视为1

>>> 5 + True
6
>>> True * 2
2
>>> 3. / (True + True)
1.5

虽然 True 是 bool 而 1 是 int:

>>> type(True)
<class 'bool'>
>>> type(1)
<class 'int'>

因为1 in st 返回True,我认为你不应该有任何问题。这是一个非常奇怪的结果。如果您有兴趣进一步阅读,@Lattyware 指向PEP 285,它深入解释了这个问题。

【讨论】:

  • 有趣的是,1True 在表示完全不同时被认为是相等的。
  • @MarkRansom 我同意,我几乎称这是一个缺陷?我很想听听 Guido 解释为什么会发生这种情况。
  • 这是一个长期存在争议的问题 - 很多人希望它针对 Python 3 进行更改。最初 Python 中没有单独的 bool 类型。阅读PEP 285 了解为什么这样做。
  • @StevenRumbalski 据我了解,它的发生方式如下: 1)hash(1) 计算为等于1; 2)在集合中搜索这个哈希值; 3)找到对应的bin; 4) 在那个 bin 中有一个值 True,恰好是 1==True; 5)1 in {True} 返回True。正确的? :)
【解决方案2】:

我相信,尽管我不确定,因为 hash(1) == hash(True)1 == Trueset 认为是相同的元素。我不认为应该是这种情况,因为1 is TrueFalse,但我相信它解释了为什么你不能添加它。

【讨论】:

  • is 结果是一个实现细节,不应依赖。 == 是正确的测试。
  • +1 因为哈希等效是这里的关键,但我同意马克的观点,即您所说的 is 并不真正相关。 1 is 1 可以是 False 并且不违反文档中的任何内容(像 300 is (299+1) 这样的东西可能会给你False)。
【解决方案3】:

1 等价于 True,因为 1 == True 返回 true。结果,1 的插入被拒绝,因为集合不能有重复项。

【讨论】:

    【解决方案4】:

    如果有人有兴趣进一步研究,这里有一些链接。

    Is it Pythonic to use bools as ints?

    https://stackoverflow.com/a/2764099/1355722

    【讨论】:

      【解决方案5】:

      如果您希望项目具有相同的哈希值,我们必须使用列表。如果您绝对确定您的集合需要能够同时包含 True 和 1.0,我很确定您必须定义您自己的自定义类,可能是 dict 的薄包装。 与许多语言一样,Python 的 set 类型只是 dict 的一个薄包装,我们只对键感兴趣。

      例如:

      st = {'a', True, 'Vanilla'}
      
      list_st = []
      
      for i in st:
          list_st.append(i)
          
      list_st.append(1)
      
      for i in list_st:
          print(f'The hash of {i} is {hash(i)}')
      

      生产

      The hash of True is 1
      The hash of Vanilla is -6149594130004184476
      The hash of a is 8287428602346617974
      The hash of 1 is 1
      
      [Program finished]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        • 1970-01-01
        • 2019-08-30
        • 2019-02-08
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        相关资源
        最近更新 更多