查看原文
其他

while循环与for循环到底差在哪里?举几个例子给你看!

刘顺祥 数据分析1480 2022-09-11

前言

在上一期原创文章《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循环的使用,我会第一时间将你的留言分享给大家。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存