为什么for循环退出“for”&引用;(空字符串)在python中?

为什么for循环退出“for”&引用;(空字符串)在python中?,python,python-3.x,Python,Python 3.x,为了解释我的查询,我在下面有一个简单的代码片段,后面是我的问题 def count_vowels(s): num_vowels = 0 for char in s: if char in 'aeiouAEIOU': num_vowels = num_vowels + 1 return num_vowels print(count_vowels("")) print("" in "

为了解释我的查询,我在下面有一个简单的代码片段,后面是我的问题

def count_vowels(s):
    num_vowels = 0
    for char in s:
        if char in 'aeiouAEIOU':
             num_vowels = num_vowels + 1
    return num_vowels

print(count_vowels(""))
print("" in "aeiouAEIOU")
给出输出

0 
True
我的怀疑:

为什么空字符串
“”
为表达式返回
True

"" in "aeiouAEIOU"
但是当它与for循环一起出现时,它会跳过

for char in s:  

我的理解是空字符串是所有字符串的子集,那么为什么在for循环中使用相同的表达式时会忽略它呢?如果我在这里遗漏了什么,请随时更正。

在您询问的第二个打印命令中,
是否出现在
“aeiouAEIOU”
中,这是
正确的

但是,
的长度为0。因此for循环不会执行一次,因为没有可迭代的项。

您的理解是正确的:“空字符串是所有字符串的子集”

但是现在让我们看看当我们对序列类型(如string)使用
for
时会发生什么。假设我们有:

lst = [1, 2, 3, 4, 5]

for i in lst:
    print(i ** 2)
它实际上是转向:

index = 0
while True:
    try:
        i = lst.__getitem__(index)
    except IndexError:
        break
    print(i ** 2)
    index += 1
在您的示例中,当它尝试获取第一个项目时,它将引发异常并中断循环。因此它甚至不进入
循环的
内部。

s
中的表达式
“”为所有字符串
s
返回
True
,因为空字符串通常包含在所有字符串中:B
中的表达式
A类似于问“是否有一对索引
i
j
使得
B[i:j]==A
”这样的问题。如果
A
是空字符串,我们总是可以将
i
j
都设置为零,所以答案是肯定的

然而,对空字符串的代码点进行迭代并不会产生
”,它根本不会产生任何结果。注意:

def迭代(什么):
打印(“在{}上迭代”。格式(repr(what)))
对于以下内容中的项目:
打印(“项:{}”。格式(repr(项)))
打印(“迭代完成”)
打印()
迭代(“abc”)

迭代("它不包含字符,所以
count\u元音
中的循环会立即退出,嗯?@bipll这很好,但我的问题是为什么?你看到打印表达式了吗?它返回True。所以我实际上是在问为什么for循环会跳过一个True表达式?@mishsx iteation over string会迭代字符串中的字符。空字符串,按定义on,没有字符。它的全部用途是用作字符串的空版本。我想,可能会有一个转换,比如,字符串的最后一个字符总是空字符串,但没有这样的约定,我认为它没有什么价值。在任何情况下,这根本不是它的定义。请注意,我想
str
对象有一个奇怪的特性,即迭代它们会生成相同类型的对象,因为python没有“char”键入,它只是长度为1的字符串。@mishsx当您将此表达式作为参数进行计算以打印时,您会得到它的布尔值,即
True
。当您在body循环中对其进行计算时,您不会对其进行一次计算,因为由于迭代的字符串是空的,因此从未输入body。我不是在要求修复。我是在问函数为什么当“aeiouAEIOU”中的独立表达式
”时,de>count_元音(“”
跳过for循环本身是真的。试着在PyttVuualiSee中调试一下。我很惊讶,这在堆栈溢出之前还没有被问过。为了澄清,<代码> S/<代码>的长度是0,所以没有什么可重复的。通过一致的回答和评论,我将不得不考虑行为是按设计进行的。这是一个很好的例子。虽然我的问题的焦点更多的是关于“aeiouAEIOU”中的表达式如何表达
"
生成一个True,但不随for循环一起生成。然而,从您的示例来看,for循环的工作方式似乎有所不同。因此,您的意思是说python的for循环实现中有一种try-catch机制,导致代码跳过循环?如果是这样,您的答案将被视为已接受。但如果您提供任何文档,则会有所帮助是的,有一个try-catch机制,但它不是本文介绍的机制。查找
StopIteration
@mishsx是的。最好的证明是,尝试自己实现一个序列类型。正如你所知道的,你必须实现
\uGetItem\uuuuuu
方法。在这个函数中,你必须以某种方式指出这不是一个valid索引,为了做到这一点,您提出了一个“IndexError”异常。但结果您可以看到它将被python静音。如何进行?因为有一个“For”机制可以为您处理该异常。(正如我在回答中提到的)@Soroushbakhatiary谢谢您,先生。您的回答非常准确。它抓住了我所寻找的内容的精髓。@mishsx很乐意提供帮助。如果您想实现迭代器,您必须做几乎相同的事情(
for
使用迭代器做其他事情)在
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。