集合操作的文档说明:
注意,union()、intersection()、difference()、symmetric_difference()、issubset()和issuperset()方法的非运算符版本将接受任何可迭代对象作为参数。相反,它们基于运算符的对应方法要求它们的参数是集合。这排除了像set('abc') & 'cbs'
这样容易出错的构造,而支持更可读的set('abc').intersection('cbs')
。
通过以下实验对此进行测试:
# Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux
>>> set('ab') & set('ac')
{'a'}
# works, as expected
>>> set('ab') & 'ac'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'set' and 'str'
# doesn't work, as expected
>>> set('ab') & list('ac')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'set' and 'list'
# doesn't work, as expected
>>> set('ab') & iter('ac')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'set' and 'str_iterator'
# doesn't work, as expected
>>> set('ab') & dict(zip('ac', 'ac')).keys()
{'a'}
# works??
>>> type({}.keys())
<class 'dict_keys'>
>>> isinstance({}.keys(), (set, frozenset))
False
所以,这里有一个悖论:
- 操作符
&
用于dict_keys
对象; - 文档中说它应该只适用于集合;
dict_keys
对象不是集合。
为什么集合运算符&
与dict_keys对象一起工作?是否有其他类型可以使用?如何找到这些类型的列表?
2条答案
按热度按时间iibxawm41#
这不是完整的答案,但
dict_keys
是collections.abc.Set
的示例:nfzehxib2#
文档的这一部分是关于
set
/frozenset
类型支持的内容。实际上,set
不支持与dict_keys
示例的比较,并且它正确地返回NotImplemented
以指示不支持此操作:这个返回值表示Python应该尝试对另一个操作数执行反射操作,看看是否支持,并且成功了:
如果 *
type(left).__and__
和type(right).__rand__
都返回NotImplemented
,那么您将看到TypeError
异常。因此,没有悖论,只是数据模型中的一个微妙之处:在X1 M9 N1 X选择退出之后,向X1 M10 N1 X类型提供从右手侧处理二进制运算的机会。