Peteryo01223 发表于 2021-1-13 09:54:26

第20课:三问 if countB: # 如果为真

本帖最后由 Peteryo01223 于 2021-1-13 10:19 编辑

第20课:最后一题,小甲鱼的答案,前面几行代码,如下:
str1 = '''ABSaDKSbRIHcRHGcdDIF'''
countA = 0# 统计前边的大写字母
countB = 0# 统计小写字母
countC = 0# 统计后边的大写字母
length = len(str1)

for i in range(length):
    if str1 == '\n':
      continue

    if str1.isupper(): # 如果str1是大写字母:
      if countB: # 如果为真
            countC += 1 # 统计后边的大写字母
      else: # 如果未出现小写字母:
            countC = 0 # 清空后边大写字母的统计
            countA += 1 # 统计前边的大写字母

请看,第12行,if countB: # 如果为真,这句代码,两天了,想不通。

第3次提问:
条件语句 if countB # 如果为真,这里的 countB 初始赋值是0,即:False。什么时候,它出现了新的赋值?没有新的赋值,按说一直是0,用 if countB 语句判断一个为 0 的值,结果都是跳过,进入else 语句。读到这一行代码的时候,我总认为 countB 一直是 0 的,看不到它获得了“新”赋值的语句。

老师1的回答:
后面为小写的时候,有赋值为1的时候的。0 为 false1 为 true。
(道理我已了解,但是在以上引用的 code 中,只有 countB = 0 唯一一次赋值的语句,没看到给countB 赋“新”值。怎么回事?)

老师2的回答:
if y: 这里y就是一个变量,跟前面那个countB是一样的。
countA是一个变量,给他赋值之后,countA就是0了,然后再str等价于str。
(感觉没说到一起去,鸡同鸭讲了)

只好再次求助~


jackz007 发表于 2021-1-13 10:34:43

本帖最后由 jackz007 于 2021-1-13 10:40 编辑

for i in range(length):
. . . . . .
    if str1.isupper(): # 如果str1是大写字母:
      if countB: # 如果已经出现小写字母:
. . . . . .
    if str1.islower(): # 如果str1是小写字母:
. . . . . .
                countB = 1 # countB记录
      这是一些相关代码
      if countB 在 countB 不为 0 的时候条件成立,既然 countB 不为 0 那就说明前面的循环已经碰到了 if str1[ i ] . islower() 为 True 的情况,当然,尽管 countB 被赋值为 1 需要满足十分苛刻的条件。就是说,正常情况下,当前这个大写字母应该属于 passwd 小写字母之后 3 个大写字母中的一个。

Peteryo01223 发表于 2021-1-13 10:38:57

本帖最后由 Peteryo01223 于 2021-1-13 10:44 编辑

jackz007 发表于 2021-1-13 10:34
这一这些相关代码
    if countB 在 countB 不为 0 的时候条件成立,既然 countB 不为 0 那就说 ...

(以你这8行code为例)是不是说:在for循环里,if countB:这个条件判断语句,虽然首先出现在了第4行,但其“新”的赋值语句,是出现在第8行。看for循环,务必要从头到尾?否则会看不到与前面的条件语句相关的赋值,因为新的赋值的那一行代码是出现在整个 for 循环的末尾的,对吗?

jackz007 发表于 2021-1-13 10:44:19

Peteryo01223 发表于 2021-1-13 10:38
(以你的8行code为例)就是说,在for循环里,if countB:虽然出现在第4行,但其“新”的赋值语句,是出现 ...

          这 8 行代码是从你贴出来的 "标准答案" 中摘出来的。为了突出问题而有所裁剪。
          从这 8 行代码可以看到,countB 确实是在当前字符为小写字母的时候被赋值。

jackz007 发表于 2021-1-13 10:46:58

本帖最后由 jackz007 于 2021-1-13 10:57 编辑

Peteryo01223 发表于 2021-1-13 10:38
(以你这8行code为例)是不是说:在for循环里,if countB:这个条件判断语句,虽然首先出现在了第4行, ...

    if str1.isupper(): # 如果str1是大写字母:
. . . . . .
    if str1.islower(): # 如果str1是小写字母:
      循环是什么,就是一些语句被多次反复执行。上面的两个条件互斥,就是说,任何时候,两个条件中,只能有一个是成立的,所以,尽管语句位置有先后,但是却并不代表它们有前后执行顺序。因为,只有一个语句块中的语句能够得到执行。

Peteryo01223 发表于 2021-1-13 11:03:43

本帖最后由 Peteryo01223 于 2021-1-13 11:10 编辑

jackz007 发表于 2021-1-13 10:46
循环中的这两个条件判断是互斥的,就是说,任何时候,这两个条件只能有一个是成立的,所以,尽 ...

好像理解了,感谢。

我有个总结:对于大型(多行的code) for 循环,必须让大脑中有“缓存”,即:不能按一般认知的顺序看代码,而应该,一边阅读,一边让各行语句同时出现在大脑中,因为有前后倒置出现。

例如,阅读小甲鱼本题的标准答案,算上空行有68行:对countB进行真假判断这一句code,虽然出现在了 for 循环的前部(答案的第13行),但实际上 countB 从初始值 0 变为 1,是出现在后部(答案的第30行)。看到第13行判断 if countB,要把它放进大脑“缓存”,然后看到第30行时,发现countB不是一直为0,而是有新的赋值的可能的,相互对应上了,“人脑”才豁然开朗。

感觉真是难啊。如果,中间几对儿代码间,隔了若干行,且有交叉,python固然不怕,缓存很大,但阅读code的人,真得具备有效的“人脑缓存”,才行。
页: [1]
查看完整版本: 第20课:三问 if countB: # 如果为真