1

在 Python 3.7 中,我想计算两个字典键的交集。为此,我想.intersection()在他们的 上调用该方法keys(),但是它不起作用。

.keys() 产生一个类似集合的对象,但是大多数集合方法都不能处理它。然而,有效的是类集合对象的极其未知的按位运算符重载,例如&.

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()类似or的方法名称.union()是自记录的,并且根据这个定义肯定更 Pythonic。

那为什么不支持呢?甚至文档也列出了别名之类的&.intersection()方法,更不用说仅&在类似集合的对象上受支持。

注意:出于某种原因,在 IPython 中,自动完成列表.isdisjoin()作为一种方法在dict.keys(). 在 17 种方法中,存在 1 种。

4

2 回答 2

2

dictviews 只保证 的 APIcollections.abc.Set,不等同于set自身:

对于类似集合的视图,为抽象基类定义的所有操作collections.abc.Set都可用(例如,==<^)。

因此,他们并没有声称 match set,甚至frozenset,只是collections.abc.Set collections.abc.Set不需要任何命名方法isdisjoint(没有等效的运算符)。

至于为什么 collections.abc.Set不需要命名方法,可能是因为它们有点复杂(大多数采用可变参数,可变参数可以是任何可迭代的,而不仅仅是其他类似集合的东西,所以你可以,例如,intersection有很多一次迭代),并且他们可能想要限制实现新子类(尤其是虚拟子类,它不会继承任何collections.abc.Set可能选择提供的方法)所需的复杂性。

综上所述,我大体同意你的观点,即省略方法形式似乎不必要地不一致。我建议您在请求更改的 Python 错误跟踪器上打开一个错误;仅仅因为它只保证Set兼容性并不意味着它不能做更多。

于 2018-11-01T02:34:54.023 回答
0

格式应该是

set.intersection(*others)

other 是任何可迭代的。m.keys() 是 dict_keys 不是一个集合,所以它不起作用。

set(m.keys()).intersection(n.keys())

将工作 :)

于 2018-11-01T02:17:36.290 回答