在Python 3.7中,我想计算两个字典键的交集。为此,我想在其.intersection()
上调用keys()
方法,但是它不起作用。
.keys()会生成一个类似于set的对象,但是大多数set方法对此均不起作用。但是,对于&
这样的集合对象,极其未知的按位运算符重载是有效的。
m = {'a':1, 'b':2}
n = {'b':3, 'c':4}
m.keys().intersection(n.keys()) # Pythonic, but doesn't work
m.keys() & n.keys() # works but not readable
set(m.keys()).intersection(set(n.keys())) # works, readable, but too verbose
我发现类似集合的对象上的&
重载极少使用,大多数程序员都不知道。 .intersection()
或.union()
之类的方法名称是自记录的,并且根据此定义,其定义肯定更像Python。
为什么不支持它?甚至documentation都列出了&
和.intersection()
这样的方法,例如别名,更不用说在类集合对象上仅支持&
了。
注释:出于某种原因,在IPython中,自动完成列表将.isdisjoin()
列为dict.keys()
上可用的方法。在这17种设置方法中,有1种。
答案 0 :(得分:2)
dict
views only guarantee the API of collections.abc.Set
,不等同于set
本身:
对于类似集合的视图,为抽象基类
collections.abc.Set
定义的所有操作都是可用的(例如==
,<
或^
)。
因此,他们并没有声称匹配set
甚至是frozenset
,而只是声称collections.abc.Set
collections.abc.Set
doesn't require any of the named methods aside from isdisjoint
(没有等效的运算符)。
关于为什么 collections.abc.Set
不需要命名方法,可能是因为它们有些复杂(大多数采用varargs,而varargs可以是任何可迭代的,而不仅仅是其他类似集合的东西,例如您可以同时intersection
具有多个可迭代对象),并且它们可能想要限制实现新子类(尤其是虚拟子类,它不会继承任何子类)所需的复杂性collections.abc.Set
的方法中可以选择提供)。
所有这些,我通常同意您的观点,即省略方法表格似乎是不必要的矛盾。建议您打开the Python bug tracker上的错误以请求更改;仅仅因为它仅保证Set
的兼容性并不意味着它不能做更多的事情。
答案 1 :(得分:0)
格式应为
set.intersection(*others)
其他是可迭代的。 m.keys()不是dict_keys集合,因此无法正常工作。
set(m.keys()).intersection(n.keys())
将起作用:)