一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习。
声明:本人学习是在扇贝编程通过网络学习的,相关的知识、案例来源于扇贝编程。如果使用请说明来源。
for循环和while循环辨别
相同点:
它俩最大的相同点是都是循环,且都有循环体和缩进。缩进是 Python 中用来表示层级关系的,非常的重要,缩进错误会导致代码运行结果不符合预期甚至报错,这里再强调一下。
不同点:
它俩最大的不同点在于循环次数是否确定。我们再来回忆一下两种循环的停止条件:while 循环 是在条件不满足时停止循环。for 循环 是遍历完整个序列的元素就停止循环。
因此,while 循环 更适合循环次数不确定的情况,而 for 循环 更适合循环次数确定的情况。
Break和continue比较
相同:
break 和 continue 它俩都只能用于循环内,且都是用于跳过循环。
不同点
所以 break 和 continue 语句的区别就是:break 语句用于在特定条件下 结束循环,continue 语句用于在特定条件下 跳过当前循环体中的剩余语句,继续进行下一轮循环。
练习:输入密码
小贝用循环写了个密码检测器,总共有 3 次试错机会。但小贝发现,不管输入的密码正确与否,都要输 3 遍才行。正确的做法应该在密码正确时结束。你能帮小贝解决这个问题吗?
i = 0
while i < 3:
i = i + 1 #这个可以放在这里
# input() 函数可以获取用户输入的字符串
password = input('请输入密码')
i = i + 1 #这个也可以放在这里
if password == '520':
print('密码正确')
break
i = i + 1 #这个不不不不可以放在这里,否则输入不正确的时候,永远还有三次机会,因为i一直是等于0 ,这里的赋值,不会用到else中。
else:
print('密码错误,你还有' + str(3-i) + '次机会')
zip()函数
zip() 函数和range()结合使用,可以同时遍历多个列表。(range()和for循环也能一起使用,遍历)
例子:
names = ["吴承恩", "罗贯中", "施耐庵", "曹雪芹"]
books = ["西游记", "三国演义", "水浒传", "红楼梦"]
for name, book in zip(names, books):
print(book + '的作者是' + name)
# 输出:
# 西游记的作者是吴承恩
# 三国演义的作者是罗贯中
# 水浒传的作者是施耐庵
# 红楼梦的作者是曹雪芹
zip()函数返回结果是元组,需要用list改成列表,列表的元素是元组。
names = ["吴承恩", "罗贯中", "施耐庵", "曹雪芹"]
books = ["西游记", "三国演义", "水浒传", "红楼梦"]
name_and_book = zip(names, books)
print(list(name_and_book))
# 输出:[('吴承恩', '西游记'), ('罗贯中', '三国演义'), ('施耐庵', '水浒传'), ('曹雪芹', '红楼梦')]
通过 list() 函数转换后可以看到,它里面的元素是一个个元组。name, book 这样用逗号分隔开的写法可以获取到元组中对应的元素。这里其实又解锁了元组的一个新知识,可以用逗号分隔开的变量获取元组里的各个元素。
# 3 个元素也同样可以
a, b, c = ('我', '爱', 'Python')
print('a =', a)
print('b =', b)
print('c =', c)
# 输出:
# a = 我
# b = 爱
# c = Pytho
names = ["吴承恩", "罗贯中", "施耐庵", "曹雪芹", "小贝"]
books = ["西游记", "三国演义", "水浒传", "红楼梦"]
for name, book in zip(names, books):
print(book + '的作者是' + name)
# 输出:
# 西游记的作者是吴承恩
# 三国演义的作者是罗贯中
# 水浒传的作者是施耐庵
# 红楼梦的作者是曹雪芹
可以看到,老师只给 names 列表添加了一个元素,结果和之前还是一样的。因此结论是:当用 zip() 函数同时遍历两个列表时,如果两个列表长度不一样,遍历次数以长度短的列表长度为准。
练习:遍历两个列表
左青龙
右白虎
前朱雀
后玄武
directions = ['左', '右', '前', '后']
animals = ['青龙', '白虎', '朱雀', '玄武']
for direction, animal in zip(directions, animals):
print(direction + animal)
最后一行改成,号连接的话,连个部分之间是有空格的。
Print(direction, animal) 结果是 左 青龙
enumerate() 函数
老师还想给你介绍一个和新的列表相关的函数——enumerate() 函数。
enumerate,这个单词是“列举、枚举”的意思。enumerate() 函数的用法很简单,它的作用是同时给出序列的元素索引和元素。你看完下面这个例子你就明白是什么意思了:
names = ["吴承恩", "罗贯中", "施耐庵", "曹雪芹"]
for index, item in enumerate(names):
print(index, item)
# 输出:
# 0 吴承恩
# 1 罗贯中
# 2 施耐庵
# 3 曹雪芹
可以看到,index 是列表中元素的索引,item 是列表中对应的元素。写法是不是和 zip() 函数结合的 for 循环很像?我想你应该猜出 enumerate() 函数的返回值长啥样了吧,我们来验证一下:
names = ["吴承恩", "罗贯中", "施耐庵", "曹雪芹"]
print(list(enumerate(names)))
# 输出:[(0, '吴承恩'), (1, '罗贯中'), (2, '施耐庵'), (3, '曹雪芹')]
enumerate() 函数返回值是 enumerate 类型,zip() 函数返回值是 zip 类型,都需要用 list() 函数转换
练习:报数程序
在没有学 enumerate() 函数之前,小贝写了一个报数的程序。现在你掌握了 enumerate() 函数,快来帮小贝用 enumerate() 函数改进一下代码吧!
初始程序:
names = ['小贝', '闻闻', '帮主']
index = 1
for item in names:
print(item + str(index))
index += 1
修改之后
names = ['小贝', '闻闻', '帮主']
for index, item in enumerate(names): #最初把index写在后面,结果报错了。因为打印的时候,索引是打印在后面的,所以我这里也写在后面。
但是enumerate在提前列表的元素和索引时,只能是索引在前,元素在后。
print(item + str(index + 1))
练习:密码破解
网络攻防听上去很高端、很难懂,但有些概念其实很简单。比如密码破解,最简单的方式就是暴力破解,也就是穷举法。人工手动地去一个一个试密码既耗时又耗力,而这种事对计算机来说可是小菜一碟。
接下来,我们来写一个简单的密码破解器。为了方便穷举、快速破解密码,我们规定密码只有 4 位纯数字。因此,只需要穷举 1000-9999 之间的所有数字和密码对比即可。
拓展:现实中的密码更加复杂,破解起来也更耗时。而且软件会限制你尝试的次数,所以暴力破解是密码破解的下下策。
from random import randint
a = 9876
while True:
number = randint(1000, 9999) #和第一句要一起使用,不能只用第二句
if number == a: # 最初等号只写了一个,后面的冒号也忘记了
break
print(number)
我的这个程序使用的是随机生成一个四位数,然后比对,从而破解。
password = 2349
i = 1000
while i != password:
i = i + 1
if i == password:
break # 这两个可以去掉,因为i不等于密码的时候,才循环,否则就退出循环,打印i,所以这里不需要跳出循环的语句。
print(i)
password = 2349
i = 1000 #这个初始值也不需要,因为range()会遍历范围内的每个值,这个就不需要
for i in range(1000, 9999):
i = i + 1 #这个也可以不要,因为是遍历每个数字,然后比对的,所以不需要慢慢增加
if i == password:
break
print(i)
网友评论