循环是程序设计语言中非常重要的语法。有了循环,我们就能处理重复事件。下面的代码说明了for循环的基本流程。
for循环
num_list = [5,2,4,7,3,6,8,1,9,0]
num_list.sort()
for num in num_list: # 每次循环,num都会获得num_list中的下一个元素,直到遍历完num_list为止。(这其实是赋值行为)
print(num) # 循环执行print(num)来进行打印
程序执行结果如下所示:
注意到for循环之后有个冒号,python以冒号开始一段代码段。要求这段代码段必须是同样的缩进。例如上面代码中的print就进行了缩进。当然了for循环可以执行一大堆的代码段。这不限于一行代码。例如:
num_list = [5,2,4,7,3,6,8,1,9,0]
num_list.sort()
for num in num_list: # 每次循环,num都会获得num_list中的下一个元素,直到遍历完num_list为止。
print(num) # 循环执行print(num)来进行打印
print(num+1)
print(num+2)
不过,正如上面所言,一个代码段的缩进必须是相同的,不然会造成语法错误。缩进是python语法的一部分。python强制要求缩进,其实是非常好的做法。这能够避免游戏人写出非常多层的嵌套代码。个人建议嵌套层数不要超过5层,超过5层的就封装成函数来进行调用,使得逻辑变得更加清晰。
num_list = [5,2,4,7,3,6,8,1,9,0]
num_list.sort()
for num in num_list: # 每次循环,num都会获得num_list中的下一个元素,直到遍历完num_list为止。
print(num) # 循环执行print(num)来进行打印
print(num+1)
print(num+2)
print("for循环执行结束") # for循环体之外的语句。这行的缩进是和for本身一样,他并不是for循环体内的代码
执行结果如下所示:
由于python中缩进是语法的一部分,因此,只有合法的缩进才能让程序正常运行。错误的缩进通常会导致语法错误,但也有些会导致逻辑错误,比如你少缩进了一行,那么这行将不属于那块代码块,从而导致逻辑错误。当然了错误的缩进导致语法错误很常见,例如在没有冒号的地方,开始缩进,那么将会导致错误,还有一些错误是缩进的幅度不同引起的,上面缩进了4个空格,但是下面缩进了3个空格,这也将会导致错误。甚至有时候,你忘记写冒号,然后接下来的代码开始进行缩进,这也会导致错误。总之多加练习能够避免这些错误。
for循环完整形式
for target in objects:
...
else:
...
其中的else部分是可选的,通常我们见到的for循环可能都不会包含else部分。else部分会在循环正常结束(没遇到break)之后执行。
while循环
for 循环用于针对集合中的每个元素都执行一个代码块,而 while 循环则不断运行,直到指定的条件不满足为止。
这也是Python为什么保留了for和while循环,他们的功能是有差异的。这不像C语言中的for循环和while循环。Python的for循环每一次取出来的都是集合中的一个元素,而不是该元素的索引。有时候,我们的某些算法,需要使用索引完成,而不是使用元素本身。下面是while循环的一个例子:
#python中,while循环比较简单。例如下面这是一个死循环,while后面的条件一直为真。
while True:
print(123)
print("ABC")
程序将会循环打印123和ABC,下面是程序的执行结果:
下面再来一个例子,这个例子使用循环打印1—5.
i = 1
while i <= 5:
print(i)
i = i+1
程序执行结果如下所示:
在循环中(包括for循环和while循环),我们可以使用break和continue来控制循环的执行。
break 可以使得循环提前结束
continue 可以提前结束本次循环。
这些用法和C语言的用法没有什么区别。
下面是例子:
i = 0
while True:
i = i+1
print(i)
if i == 3: # i等于100的时候,循环结束。
break
print("\n")
i = 0
while True:
i = i+1
if i == 5: # i等于5的时候,提前结束本次循环
continue
print(i)
if i == 10:
break # i == 10的时候,循环结束。
程序执行结果如下所示:
如果对Python的语法和特性非常熟悉,那么有的算法写起来就很Python,下面是几个例子,这些例子,如果从C语言的角度考虑,那么代码将会变多,没有这么优美,有的甚至会变得很复杂。前两个例子是书上的,后面的例子是我某次看到的。
在列表之间移动元素:
# 首先,创建一个待验证用户列表
# 和一个用于存储已验证用户的空列表。
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []
# 验证每个用户,直到没有未验证用户为止。
# 将每个经过验证的用户都移到已验证用户列表中。
while unconfirmed_users:
current_user = unconfirmed_users.pop()
print(f"Verifying user: {current_user.title()}")
confirmed_users.append(current_user)
# 显示所有已验证的用户。
print("\nThe following users have been confirmed:")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
删除列表中的特定值
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets)
去除列表中重复的值:
cve_list1 = ["Red Hat Mozilla Firefox和Firefox ESR 安全漏洞(CVE-2019-11708)"
,"Red Hat systemd 安全漏洞(CVE-2018-15686)"
,"Red Hat Haxx curl 缓冲区错误漏洞(CVE-2018-14618)"
,"Red Hat Haxx curl 缓冲区错误漏洞(CVE-2018-14618)"
,"Red Hat Linux kernel Marvell WiFi chip driver 缓冲区溢出漏洞(CVE-2019-14901)"
,"Red Hat Linux kernel Marvell WiFi chip driver 缓冲区溢出漏洞(CVE-2019-14901)"
,"Red Hat GNU wget栈缓冲区溢出漏洞(CVE-2017-13089)"
,"Red Hat Mozilla Firefox 释放后重利用漏洞 (CVE-2019-11752)"
,"Red Hat Artifex Ghostscript 安全漏洞(CVE-2018-16509)"
,"Red Hat Artifex Ghostscript 安全漏洞(CVE-2018-16509)"
,"Red Hat reposync 安全漏洞(CVE-2018-10897)"
,"Red Hat reposync 安全漏洞(CVE-2018-10897)"
,"Red Hat GNU patch 操作系统命令注入漏洞(CVE-2018-20969)"
,"Red Hat Vim和Neovim 操作系统命令注入漏洞(CVE-2019-12735)"
,"Red Hat libssh2 输入验证错误漏洞(CVE-2019-3855)"
,"Red Hat libssh2 输入验证错误漏洞(CVE-2019-3855)"
,"Red Hat GNU C Library 'elf/dl-load.c ' 本地权限提升漏洞(CVE-2017-16997)"
,"Red Hat GNU C Library 'elf/dl-load.c ' 本地权限提升漏洞(CVE-2017-16997)"
,"Red Hat Artifex Software Ghostscript 安全漏洞(CVE-2018-16863)"
,"Red Hat Artifex Software Ghostscript 安全漏洞(CVE-2018-16863)"
,"Red Hat GNU wget堆缓冲区溢出漏洞(CVE-2017-13090)"
,"Red Hat GNU patch 操作系统命令注入漏洞(CVE-2019-13638)"
,"Red Hat GNU patch 操作系统命令注入漏洞(CVE-2018-20969)"
,"Red Hat GNU patch 操作系统命令注入漏洞(CVE-2019-13638)"
,"Red Hat PolicyKit 安全漏洞(CVE-2018-19788)"
,"Red Hat PolicyKit 安全漏洞(CVE-2018-19788)"
,"Red Hat Sudo 输入验证错误漏洞(CVE-2019-14287)"
,"Red Hat Sudo 输入验证错误漏洞(CVE-2019-14287)"
,"Red Hat Mozilla Thunderbird、Firefox ESR和Firefox 安全漏洞(CVE-2020-12387)"
,"Red Hat Mozilla Firefox和Firefox ESR 安全漏洞(CVE-2020-12395)"
,"php安全漏洞(CVE-2018-19518)"
,"Red Hat Gluster 安全漏洞(CVE-2018-14654)"
,"Red Hat Linux kernel 缓冲区错误漏洞(CVE-2017-1000251)"
,"Red Hat Linux kernel 安全漏洞(CVE-2018-14633)"
,"Red Hat Linux kernel 安全漏洞(CVE-2018-14633)"
,"Red Hat Linux Kernel 'marvell/mwifiex/scan.c'堆溢出漏洞(CVE-2019-3846)"
,"Red Hat Linux Kernel 'marvell/mwifiex/scan.c'堆溢出漏洞(CVE-2019-3846)"
,"Red Hat Linux kernel rtl_p2p_noa_ie缓冲区溢出漏洞(CVE-2019-17666)"
,"Red Hat Linux kernel rtl_p2p_noa_ie缓冲区溢出漏洞(CVE-2019-17666)"
,"Red Hat Broadcom brcmfmac driver 缓冲区错误漏洞(CVE-2019-9500)"
,"Red Hat Broadcom brcmfmac driver 缓冲区错误漏洞(CVE-2019-9500)"
,"Red Hat Broadcom brcmfmac driver 安全漏洞(CVE-2019-9503)"
,"Red Hat DHCP Client Script代码执行漏洞(CVE-2018-1111)"
,"Red Hat Linux kernel 缓冲区错误漏洞(CVE-2019-9503)"
,"Red Hat GNU C Library 资源管理错误漏洞(CVE-2014-9402)"
,"Red Hat Linux kernel 安全漏洞(CVE-2018-5391)"
,"Red Hat Linux kernel 安全漏洞(CVE-2018-5391)"
,"Red Hat Linux kernel 'tcp_input.c'远程拒绝服务漏洞(CVE-2018-5390)"
,"Red Hat Linux kernel 'tcp_input.c'远程拒绝服务漏洞(CVE-2018-5390)"
,"Red Hat 389 Directory Server 安全漏洞(CVE-2018-14648)"
,"Red Hat Linux kernel 输入验证错误漏洞(CVE-2019-11477)"
,"Red Hat Linux kernel 输入验证错误漏洞(CVE-2019-11477)"
,"Red Hat Dnsmasq 整数溢出漏洞 (CVE-2017-14496)"
,"Red Hat Linux kernel 代码问题漏洞(CVE-2019-11810)"
,"Red Hat Linux kernel 代码问题漏洞(CVE-2019-11810)"
,"Red Hat Linux kernel 缓冲区错误漏洞(CVE-2019-15916)"
,"Red Hat Linux kernel register_queue_kobjects()拒绝服务漏洞(CVE-2019-15916)"
,"Red Hat Linux kernel 竞争条件漏洞(CVE-2017-10661)"
,"Red Hat Linux kernel 竞争条件漏洞(CVE-2017-10661)"
,"PHP 栈缓冲区溢出漏洞(CVE-2018-7584)"
,"PHP 缓冲区错误漏洞(CVE-2019-9023)"
,"PHP 安全漏洞(CVE-2019-9020)"
,"PHP 安全漏洞(CVE-2019-9021)"
,"Paramiko SSH服务器实现安全漏洞(CVE-2018-7750)"
] # 表1是含有重复漏洞名称的
cve_list2 =[] # 去重结果放入表2
for i in cve_list1: # 遍历表1
if i not in cve_list2: # 如果表1中数据在表2中不存在,那么追加进表2,从而完成去重。
cve_list2.append(i) # 去重的结果顺序在表1的基础上是不变的。
for cve in cve_list2:
print(cve)
while循环完整形式
while condition:
...
else:
...
其中的else部分是可选的,通常我们见到的while循环可能都不会包含else部分。else部分会在循环正常结束(没遇到break)之后执行。