为什么“ in”运算符识别子字符串而不识别子列表?

时间:2019-03-09 05:37:12

标签: python

这是为什么呢?

'bcd' in 'abcde'

但这是错误的:

[2,3,4] in [1,2,3,4,5]

这些陈述在概念上是相同的,不是吗? in运算符是否有针对字符串的特殊规则?

2 个答案:

答案 0 :(得分:4)

列表可以包含在列表中。

[[2, 3, 4], 2, 3, 4, 5]

其中一次遍历外部列表一个元素

[2,3,4] in [[2, 3, 4], 3, 4, 5]

为您提供True

在这种情况下,没有等效的字符串。

您可以通过子类化列表并更改@hpaulj指出的__contains__来创建新类型。

但是在您开始之前有一些问题吗?

您希望在其中找到[2,3,4]多少次?

[[2, 3, 4], 2, 3, 4, 5]

或这个

[[2,3,4], [2],[3],[4],5]

答案 1 :(得分:0)

评论

让我们看一下左/右超集数据结构及其元素:

|           Example           | Structure | Element |
|-----------------------------|-----------|---------|
|  'bcd'     in    'abcde'    | str       | str     |
|  [0, 1, 2] in [0, 1, 2, 3]  | list      | int     |

我怀疑原理如下:

  • 当数据结构和元素类型相等时,in比较是明确的,例如字符串的子字符串。
  • 当数据结构和元素类型不相等时,in模棱两可。

让我们更加仔细地研究这种模糊性。

讨论

给予

[0, 1, 2] in [0, 1, 2, 3]

我们在比较

  1. 元素容器(默认)?
  2. 仅仅是元素?

如果使用方法2,其中in仅比较元素,则

[0, 1, 2] in [0, 1, 2, 3]
(0, 1, 2) in [0, 1, 2, 3]
{0, 1, 2} in [0, 1, 2, 3]

每个应该返回True,因为0, 1, 2是在左右容器中共享的元素。这样的比较不考虑容器的类型。这种方法限制了in,特别是因为元素比较可以通过集合完成:

set([0, 1, 2]) < set([0, 1, 2, 3])
# True

set([0, 1, 2]).issubset([0, 1, 2, 3])
# True

摘要

  1. 将容器+元素比较留给in
  2. 将严格的元素比较留给set()