while循环与for循环到底差在哪里?举几个例子给你看!
前言
在上一期原创文章《for循环太Low?分享几段我工作中经常使用的for代码!》中,我介绍了几段工作中常用的for循环代码,这期再简单介绍一下while循环与for循环的差异。
在作者看来,while循环与for循环的最大区别在于,while循环是基于条件判断的循环,而for循环则是基于容器的循环。对于while循环来说,当条件满足时,将一直处于循环状态,除非碰见break关键词;对于for循环来说,当容器内的元素没有迭代结束,则一直处于循环状态,同样碰见break关键词时也会退出循环。
所以,在做循环问题时,首先自问循环过程中有没有明确的迭代对象(即容器),然后再根据判断结果,选择优先方案,即如果有迭代对象,则优先使用for循环,否则优先使用while循环。相信读者在后文的循环实操中,能够感受到优先所带来的便捷。
while循环示意图及语法
为帮助读者理解while循环的逻辑,我将循环逻辑绘制成了下方的示意图,读者可以慢慢体会一下它与for循环的差异:
如上图所示,当数据输入后,会立马进入条件判断,如果条件满足,则进入循环体,并继续下一轮的循环,直到条件不满足时,退出循环。所以,根据该逻辑,可以将while循环的语法表示如下:
# while循环通常会有初始值,这里不妨设置变量s的初始值为0
s = 0
# 无分支判断的for循环
while condition:
statements
s = 0
# 有分支判断的for循环
while condition:
if condition:
statements1
else:
statements2
while循环的几个综合案例
由于绝大多数的循环问题,都可以使用while循环或者for循环解决,为了表现while循环的优势,接下来举两个特殊的案例,体现while循环的优势。
案例1:在[a,b]区间内猜一个整数
# 导入第三方模块
import random
# 设定被猜数据的范围
A = int(input('请输入被猜数据范围的最小值:'))
B = int(input('请输入被猜数据范围的最大值:'))
# 生成A,B之间的一个随机整数
number = random.randint(A,B)
while True:
guess = int(input('请在{}和{}之间猜一个整数:'.format(A,B)))
if guess > number:
# 如果猜的偏大,则将猜的数字重新赋值给B,用于限定下一轮数据的猜测范围
B = guess
print('不好意思,您猜大了!')
elif guess < number:
# 如果猜的偏小,则将猜的数字重新赋值给A,用于限定下一轮数据的猜测范围
A =guess
print('不好意思,您猜小了!')
else:
print('恭喜,您猜正确了!')
# break用于退出整个while循环
break
如上代码所示,进入while循环之前设定了三个初始值,用于限定被猜数据的范围以及该范围内的一个随机整数。读者会发现,while关键词后面不是一个具体的判断条件,而是布尔值True,这意味着while循环属于死循环(即永远不会出现条件为假而退出循环的可能)。为保证while循环可以正常退出,循环体内设置了break关键词(当用户猜对后,循环语句会来到break关键词)。
案例2:抓取未知页数的网站数据
如下图所示,对于抓取的目标网站中,不清楚数据可能会涉及多少页内容(图中的7并不代表最后的尾页数字),即意味着循环过程中不明确具体的容器对象是什么,所以我们应想到使用while循环解决问题。
# 导入第三方模块
import requests # 用于发送URL请求
import bs4 # 用于解析HTML语言
import random # 用于生成随机数
import time # 用于时间滞留
from fake_useragent import UserAgent # 用于生成随机请求头
import pandas as pd # 用于构造数据表
# 初始化网站页数
page = 1
# 构造字典容器,用于存储每一页汽车信息
car_info = {}
# 构造列表容器,用于存储所有页汽车信息
final_result = []
while True:
# 生成有规律的链接
URL = r'https://www.renrenche.com/sh/kaidilake/p{}/?brand=kaidilake'.format(page)
print('Down Loading{} ...'.format(URL))
# 生成随机请求头
UA = UserAgent()
# 对URL发送请求
response = requests.get(URL, headers = {'User-Agent':UA.random})
# 解析抓回来的HTML源代码
soup = bs4.BeautifulSoup(response.text)
# 判断该页码内是否有抓取的对象
name = [i.text for i in soup.findAll(name = 'h3')]
if len(name) != 0:
# 抓取凯迪拉克汽车系列名称
car_info['name'] = name
# 抓取汽车基本信息
car_info['basic'] = [i.text.strip() for i in soup.findAll(name = 'div', attrs = {'class':'mileage'})]
# 抓取汽车价格信息
car_info['price'] = [i.text.strip() for i in soup.findAll(name = 'div', attrs = {'class':'price'})]
else:
break
# 存储所有页码的汽车信息
final_result.append(pd.DataFrame(car_info))
# 产生随机秒数
seconds = random.uniform(3,5)
# 滞留指定的秒数
time.sleep(seconds)
# 累加页码
page += 1
# 将所有页码下的汽车数据汇总到一张表内
kaidilake = pd.concat(final_result)
# 呈现数据集的前5行
kaidilake.head()
如上代码涉及的内容非常多,读者可以仔细阅读每一行代码所对应的注释内容,这里侧重主要分享一下while循环的逻辑:
未知具体容器时,优先选择while循环,并让while循环进入死循环状态;
当网页中的目标数据可以抓取时,便不停地增加page值;
当网页中的目标数据无法抓取时,意味着已经到达最后一页的下一页,此时通过break关键词断开循环;
从下图可知,当page到达13时,直接输出了数据集的前5行信息,说明while循环已结束。进一步可知,该爬虫过程一共抓取了12页的有效数据。
结语
OK,今天的内容就分享到这里,如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位大咖在留言区分享你们对while循环的使用,我会第一时间将你的留言分享给大家。