【问题标题】:Difference operations in dictionary keys in pythonpython中字典键的差异操作
【发布时间】:2017-10-16 10:37:48
【问题描述】:

我正在使用 IDLE 运行一些 Python3 代码,我想了解为什么

a = {'a':1,'b':2}

两者:

a.keys()-'a'

(甚至不知道为什么这个有效)和

a.keys()-{'a'}

产生相同的结果。


奇怪的是,一旦在函数内部执行操作(并从 IDLE 调用)或直接从 IDLE 运行,第二个选项似乎会产生不同的输出...

【问题讨论】:

    标签: python dictionary set set-difference


    【解决方案1】:

    字符串是可迭代的字符——set('abc') == {'a', 'b', 'c'}。 dict 键的 - 运算符接受任何可迭代的,因此 'a' 等效于 {'a'}

    如果您使用更长的字符串,它似乎不再起作用了。

    【讨论】:

    • 如果您提到dict.keys 的文档说它返回字典键的类似集合的对象,可能会更清楚。然后是简单的集合操作,正如您所演示的那样。
    • “a”不是“char”吗?事实上:a.keys()-chr(97) 产生相同的输出。
    • Diego 当您调用 dict.keys() 时,您将获得一个 dict_keys 实例,而另一个是 set 实例。 __sub__ 方法是为其中一个定义的,但不是为另一个定义的。
    • @Adirio 是的,我知道谢谢。这只是要注意 Reti43 的注释“简单集合操作”可能不适用。
    • @DiegoFMedina:Python 没有字符类型。 chr 返回一个单字符串。你说得对,{'a', 'b'} - 'a' 产生错误是为什么我说“字典键的运算符”而不是像 Reti43 那种建议的“集合的运算符”。 =)
    【解决方案2】:

    这里要理解的是你要减去的实体类型。

    a.keys() 是一个可迭代对象。这仅仅意味着它可以通过使用foriter 进行迭代。正式地说,在 python 中,任何东西都是实现__iter__ 函数的可迭代对象。检查这个link

    >> type(a.keys)
    >> dict_keys
    

    dict_keys 是一个可迭代的,你怎么知道的?因为它有一个属性__iter__

    >> hasattr(a.keys() , '__iter__')
    >> True
    

    a.keys() 返回一个view 对象。这允许您从自身中减去其他迭代。如文档中所述:

    dictview - other
    Return the difference between the dictview and the other object (all elements in dictview that aren’t in other) as a new set.
    

    因此,要从 a.keys() 中减去某些内容,该实体也应该是可迭代的。

    在你的情况下:

    1. a.keys() - 'a' 有效,因为字符串在 python 中是可迭代的

      >> hasattr('a' , '__iter__')

      >> True

      所以,字符串是可迭代的

    2. a.keys() - {'a'} 有效,因为{'a'} 是一个集合,它是一个可迭代的

      >> hasattr({'a'} , '__iter__')

      >> True

    另一方面,如果你尝试这样做:

    >> a.keys() - 1
    >> TypeError: 'int' object is not iterable
    

    因此,您不能减去两个不可迭代的对象。 希望这会有所帮助:)

    【讨论】:

    • 说一般可以减去两个迭代是不正确的。 rangelist 是可迭代的,但不能相减,因为它们不支持 __sub__ 方法。另一方面,集合支持该方法,因为它对那个对象有意义。
    猜你喜欢
    • 2010-11-13
    • 2012-10-09
    • 1970-01-01
    • 2018-08-11
    • 2017-11-13
    • 2018-05-10
    • 2016-05-28
    • 1970-01-01
    相关资源
    最近更新 更多