首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >开源图书《Python完全自学教程》6.3.1循环语句初步应用

开源图书《Python完全自学教程》6.3.1循环语句初步应用

作者头像
老齐
发布2022-05-17 09:44:50
发布2022-05-17 09:44:50
7100
举报
文章被收录于专栏:老齐教室老齐教室

6.3 for 循环语句

for 循环语句普遍存在多种常见的高级编程语言,在 Python 中地位尤为重要,何以见得?学然后即知。

6.3.1 初步应用

很多编程语言都继承了 C 语言的 for 循环风格,例如 JavaScript 中这样实现(以下代码不需调试):

代码语言:javascript
复制
var numbers = [1, 2, 3, 5, 7]; 
for (var i = 0; i < numbers.length; i += 1) {
    print(numbers[i]) }

像这样的还有 Java、PHP 等编程语言。如果把这种类型的称为“传统”风格的话,Python 中的 for 循环则显得特立独行,它不是 C 语言风格的,它是 Python 风格的——别具一格。

代码语言:javascript
复制
numbers = [1, 2, 3, 5, 7] 
for n in numbers:          # (1)
    print(n)

比较以上两段代码,后者是 Python 风格的 for 循环语句,与“传统”风格相比:

  • 不需要创建索引变量、不需要对索引变量初始化,没有 var i = 0
  • 不需要边界检查,没有 i < numbers.length
  • 不需要索引递增,没有 i += 1

Python 的 for 循环不仅形式上与 C 语言风格的不同,工作原理也不同,但下面还是先从形式上学习,原理内容留给以后探究。

下面以注释(1)为例,结合图6-3-1,说明 Python 的 for 循环基本用法:

  • for :发起 for 循环的关键词;
  • n :引用被循环对象中成员的变量,注释(1)中的变量 n 依次引用列表中的每个成员;
  • in :关键词,右侧的 numbers 变量引用了被循环对象。

如果将 for n in numbers 看做自然语言中的一句话,其字面含义即意味着 n 引用 numbers 中的成员。

图6-3-1 for 循环语句结构

将注释(1)的循环语句在交互模式中执行,效果如下:

代码语言:javascript
复制
>>> numbers = [1, 2, 3, 5, 7]
>>> for n in numbers:
...     print(n)
...
1
2
3
5
7

在 Python 中,只有可迭代对象才能够作为 for 循环语句中的被循环对象。关于可迭代对象,在第4章和第5章都有所介绍,第9章9.6节还会详细说明。

相传,高斯9岁时就证明了快速计算等差数列求和的技巧,即 1+2+3+\cdots+99+100 。这里我们用 Python 程序计算,并向大师致敬。

代码语言:javascript
复制
#coding:utf-8
'''
filename: sumhundred.py
'''
sum = 0
for i in range(1, 101):    # (2)
    sum += i               # (3)

print(f"the sum of 1 to 100 is: {sum}")

先看执行效果,再分析程序中的重点代码:

代码语言:javascript
复制
% python sumhundred.py
the sum of 1 to 100 is: 5050

此结果与高斯计算的结果相同——是不是充满了成就感。不过,此处的方法和高斯的明显不同,高斯使用了等差数列求和公式,这里是逐个做加法——方法虽笨,但有计算机这个好工具,所以速度很快。下面就分解这个“笨方法”,理解每一部分含义:

range() 是 Python 的内置函数,它的调用方式是 rang(stop) 或者 range(start, stop[, step]) ,参数均为整数,生成由整数组成的等差数列——返回的对象不是列表,是 range 类型对象,这种类型的对象是一种“类列表”的序列,可以用 list() 函数将其转换为列表。

代码语言:javascript
复制
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 20, 2))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
>>> 9 in range(10)
True

注释(2)中以 range(1, 101) 得到了由整数 1,2,\cdots, 100 作为成员的 range 对象,它是可迭代的,用于 for 循环。

变量 i 依次引用 range(1, 101) 中的每个整数,通过注释(3)实现“自增”计算(见6.1.1节),即完成 1+2+3+\cdots+99+100 计算。

利用 range() 函数,可以解决一些与等差数列有关的问题。例如,要求选出 50 以内能被 3 整除的非负整数,可以这样实现:

代码语言:javascript
复制
#coding:utf-8
"""
filename: divisibility.py
"""
lst = []
for i in range(50):
    if i % 3 == 0:
        lst.append(i)

print(f"numbers divisible by 3: {lst}")

执行结果是:

代码语言:javascript
复制
% python divisibility.py 
numbers divisible by 3: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

其实,如果读者认真阅读 range() 官方文档,还会找到另外一种更直接的方法:

代码语言:javascript
复制
>>> list(range(0, 50, 3))
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

在慨叹其简洁之余,更要认识到阅读官方文档的重要性。

再来看一个将字符串作为 for 循环的示例。在这个示例中,要统计一个单词中每个字母的出现次数。

代码语言:javascript
复制
#coding:utf-8
'''
filename: countchar.py
'''
word = input('please input an english word:')
result = {}                        # (4)
for e in word:                     # (5)
    if e in result:                # (6)
        result[e] += 1
    else:
        result[e] = 1
print(f'the word is: {word}')
print(f'count letter: {result}')

先看执行结果,再分析代码。

代码语言:javascript
复制
% python countletter.py 
please input an english word:zoom
the word is: zoom
count letter: {'z': 1, 'o': 2, 'm': 1}

按照“用户的输入都不可信”原则,上述程序还有待优化。但是,这里我们要将注意力放在 for 循环语句,姑且认为“人之初,性本善”的假设是成立的。

要统计单词中每个字母出现的次数,显然要建立字母与出现次数的对应关系——立刻想到了“键值对”,最适合的就是用字典类型的对象保存统计结果,于是注释(4)创建一个空字典。

注释(5)循环单词(字符串对象)中的每个成员——字母,然后在循环体(注释(6)开始的语句块)内,判断该字母是否已经是 result 的键:如果是,说明此前已经对该字母计数,所以让它对应的值“自增” 1 ;否则,在 result 中增加一个以该字母为键的键值对,并设置初始的值为 1

这样,就实现了记录对象出现次数的统计,这种方法在后续示例中还会用到。

列表和字符串都是序列,也都是可迭代对象,此外,字典虽然不是序列,但是可迭代对象,故也可以作为 for 循环语句中的被循环对象。

代码语言:javascript
复制
>>> d = dict([("website", "www.itdiffer.com"), ("lang", "python"), ("author", "laoqi")])
>>> for k in d: print(k)    # (7)
...
website
lang
author

注释(7)是一种“偷懒”的写法,在冒号 : 后面跟一个空格,然后写循环体的语句。这种写法仅适用于循环体的语句块中只有一条语句的情况。当然,将 print(t) 写在下一行(前面有四个空格)依然可行,且效果相同。

从代码的运行结果可知,注释(7)中的变量 k 依次引用了字典 d 的键值对的键(key)。

代码语言:javascript
复制
>>> for k in d.keys(): print(k)
...
website
lang
author

这段代码中使用了字典的方法 keys() (参阅第5章5.1.3节),与注释(7)等效,不过常用的还是注释(7)。

若要通过循环得到键值对中的值(value),不难想到字典的另外一个方法 values()

代码语言:javascript
复制
>>> for v in d.values(): print(v)
...
www.itdiffer.com
python
laoqi

自然还会想到字典的 items() 方法返回值也可以用于被循环对象,但是要注意,d.items() 返回值有点特别。

代码语言:javascript
复制
>>> d.items()
dict_items([('website', 'www.itdiffer.com'), ('lang', 'python'), ('author', 'laoqi')])

循环此种形式的对象,得到每组键值对的键和值:

代码语言:javascript
复制
>>> for k, v in d.items():    # (8)
...     print(f'key:{k} --> value:{v}')
...
key:website --> value:www.itdiffer.com
key:lang --> value:python
key:author --> value:laoqi

注释(8)中 (k, v)d.items() 返回值的每个成员依次循环对应引用,即 k 引用键值对的键,v 引用键值对的值。

此外,用注释(7)的循环方式,也能实现注释(8)的结果:

代码语言:javascript
复制
>>> for k in d:
...     print(f'key:{k} --> value:{d[k]}')
...
key:website --> value:www.itdiffer.com
key:lang --> value:python
key:author --> value:laoqi

以上初步了解了 for 循环的基本应用。为了让 for 循环用得更妙,Python 中的两个内置函数必须要了解。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 6.3 for 循环语句
    • 6.3.1 初步应用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档