异常信息处理

学习Python到现在,你应该已经遇到了各种各样的程序报错,什么NameError啊,SyntaxError啊,TypeError……这都是在学习程序中非常正常的过程。在Python中,我们将这些错误称为异常(exceptions)。异常实际上是一种流程控制,当异常出现时,正常的程序流程就被打断了,程序进而根据异常的种类做出相应的提示。

在我们前面的学习中,写过这样一个摄氏度与华氏度转换的程序

temp_C = eval(input('请输入现在的摄氏温度:'))
temp_F = temp_C * 1.8 + 32
print('当前温度为华氏', temp_F, '度', sep = '')

假设我们有一位耿直的用户是这么输入的:

请输入现在的摄氏温度:二十五摄氏度
Traceback (most recent call last):
  File "C:/Users/MSI/Desktop/1.py", line 1, in 
    temp_C = eval(input('请输入现在的摄氏温度:'))
  File "", line 1, in 
NameError: name '二十五摄氏度' is not defined

@%¥&#@#~!啥?这种错误提示显然对用户并不友好。这堆看不懂的东西,实际上是Python内部默认的异常处理机制(exceptions handler)。那么我们可不可以自定义异常的处理呢?

 

  • try和except命令

这是一组常用的处理异常的命令,简单的说就是先试试看try后面的代码能不能行,要是出现了异常,那就执行except后面的代码。我们把温度转换的程序改写一下,观察:

try:
    temp_C = eval(input('请输入现在的摄氏温度:'))
    temp_F = temp_C * 1.8 + 32
    print('当前温度为华氏', temp_F, '度', sep = '')

except:
    print('请用阿拉伯数字输入温度')

我们发现,try和except和前面的循环、条件写法很相像,冒号之后另起一行缩进后开始书写。改写之后,我们保存并运行,然后再次输入中文:

请输入现在的摄氏温度:二十五度
请用阿拉伯数字输入温度

啊哈,这就看得懂了。也就是说,Python在运行try之后的代码时,遇到了一个异常,因此,Python转而开始执行except后方的代码。

 

  • 本节练习

写一个猜数字游戏。从1-100之间的整数中随机抽取一个,引导用户猜数,对用户输入的数字做出“太小”、“太大”等提示,如果用户第一次输入的不是数字,提示用户只能用阿拉伯数字进行游戏。游戏表现如下:

谜底是1-100间的整数,请输入您的答案...:三十四
请输入纯阿拉伯数字啦...

谜底是1-100间的整数,请输入您的答案...:34
您猜小啦

再猜一次呗:60
您猜大啦

再猜一次呗:50
您猜大啦

再猜一次呗:40
您猜大啦

再猜一次呗:35
您猜小啦

再猜一次呗:36
猜对啦!答案是:36

看答案

import random

answer = random.randrange(1, 101)

try:
    num = eval(input('谜底是1-100间的整数,请输入您的答案...:'))
    
except:
    print('请输入纯阿拉伯数字啦...\n') #\n是换一行,方便用户看清
    num = eval(input('谜底是1-100间的整数,请输入您的答案...:'))

while num != answer:
    if num > answer:
        print('您猜大啦\n')
        num = eval(input('再猜一次呗:'))
    elif num < answer:
        print('您猜小啦\n')
        num = eval(input('再猜一次呗:'))

print('猜对啦!答案是:', answer, sep = '')

酱哦

 

如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

其他流程控制方法*

在学习了条件判断、循环等控制流程的手段之后,我们将学习一些其他语句来更灵活地对程序流程进行控制。

 

  • break和continue语句

break用以打断当前循环,并退出循环语块;continue则用以打断当前循环,但不退出循环语块。啥意思咧,我们观察下面例子:

>>> lst = [1, 2, 3, 4, 5]
>>> for num in lst:
	if num == 4:
	    break
	print(num)
	
1
2
3
>>> lst = [1, 2, 3, 4, 5]
>>> for num in lst:
	if num == 4:
	    continue
	print(num)
	
1
2
3
5

我们看到,当程序执行break时,当次的循环被打断了,因此没有打印出4,而整个循环语块也随之退出了,因此也没有打印出5;

当程序执行continue时,当次的循环被打断了,因此没有打印出4,但整个循环语跳过4之后继续,因此打印出了5。

 

  • pass语句:

有的时候,我们希望程序“什么也不做”;又或者是我们还没有想好这个地方怎么写。这时候,我们可以使用pass语句,让程序能够顺利运行。观察下面程序:

>>> lst = [1, 2, 3, 4, 6]
>>> for num in lst:
	if num % 2 != 0:
	    pass
	else:
	    print(num)
		
2
4
6

对于一个列表中的数字,如果是奇数,那什么也不做,pass。如果是偶数,那就把它打印出来。为了实现“什么也不做”我们使用了pass语句。如果不写pass而是留空,那么在程序运行的时候就会报错。

 

  • 本节练习

写一个循环,将列表[1, 6, 7, 3, 26, 81, 0 ,99, 66]中3的倍数(不含3本身)逐行打印,如遇到0则终止程序。

看答案

lst =[1, 6, 7, 3, 26, 81, 0 ,99, 68]

for num in lst:
    #思考下面if和elif条件位置互换是否可行?为什么?
    if num == 0:
        break
    elif num == 3:
        continue
    elif num % 3 == 0:
        print(num)

酱哦

 
如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

使用while循环控制流程

Python中,还有一种循环方式,可以在特定条件成立时,不断循环一块代码,在学习这种循环时,我们有时会写错代码使程序进入无限循环,这时候我们需要按下键盘上的Ctrl+C来强制结束程序(MacOS按下control+C)。

 

  • while循环

我们先看看while循环的一般性写法:

while <条件>:
    <缩进语块>

学了之前的循环后,我们就很好理解格式上的问题了。从意思上来看:只要<条件>成立(True),就一直循环执行缩进语块中的命令。

有同学就说,那写好的<条件>还能变哇?不然岂不是要么不循环要么死循环了吗?

假设我们要写一个程序,来计算金融投资时,不同的年利率需要多少年才能使本金翻一番,我们先从数学的角度梳理一下这个问题:

假设本金是1,年利率是x;
第一年连本带息我们将获得:1*(1+x);
第二年则是1*(1+x)*(1+x);
……
第n年则是1*(1+x)^n;
为了使资产“翻一番”,只要1*(1+x)^n < 2,就要执行再计算一年利息的命令

观察下面的程序:

years = 0 #我们令一个变量years初始为0,用来累加所需年限
fund = 1 #我们令一个变量fund初始为1,用来累加资产本息总和
rate = eval(input('请输入投资产品的年化利率(如10%,请输入0.1):'))

#只要资产总额小于2,我们就不断执行:年限+1 和 资产乘以(1+年利率)的操作
while fund < 2:
    years = years +1
    fund = fund * (1+rate)

print('您的资产将在', years, '年后翻一番。', sep ='') #注意本行没有缩进

我们发现,由于while后面的条件中存在一个变量,该变量在每循环一次都会发生变化,因此,当循环次数足够多时,将会出现fund > 2的情况。此时,循环终止,程序开始运行循环下方无缩进的语句。如果你写好了,保存以后按下F5测试一下吧~

 

  • 程序的逻辑
while <条件>:
    <缩进语块>

while语句和之前学习的if语句类似,只有当<条件>为True的时候,会执行下方的缩进语块。不同在于,while下方的缩进语块执行完毕之后,程序将返回while所在行,再次检查<条件>是否为True,这个过程将持续到<条件>变为False为止。

我们在使用while循环时,应注意检查<条件>是否有可能变为False,否则程序将进入无限循环。

 

  • 本节练习

试写一个无限循环的while语句,运行观察,并利用键盘打断程序运行

看答案

x = 1

while x < 2:
    print('哟')

酱哦

写一个程序,提示用户输入地名,并将用户输入的地名放入一个列表中。当用户输入空字符串”时,程序返回装有地名的列表并停止运行,运行效果如下:

请输入一个地名(结束请直接按回车):北京
请输入一个地名(结束请直接按回车):厦门
请输入一个地名(结束请直接按回车):西安
请输入一个地名(结束请直接按回车):昆明
请输入一个地名(结束请直接按回车):
['北京', '厦门', '西安', '昆明']
>>> 

看答案

place_list = []
place_name = input('请输入一个地名(结束请直接按回车):')

while place_name != '':#也可以写 while not place_name = ''
    place_list.append(place_name)
    place_name = input('请输入一个地名(结束请直接按回车):')

print(place_list)

酱哦

 
如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

使用for循环控制流程*

有时候,我们希望一块代码可以反复执行,这时候我们要用到的,就是循环~

  • for循环

假设我们有一个单词’Python’,我们想要把其中的每个字母为一行打印出来:

P
y
t
h
o
n

这就是for循环的一个经典运用场景——我们可以用for循环,遍历一个序列(字符串’Python’)中的每个元素,然后对每个元素(‘Python’中的每个字母)进行同样的操作(打印)。我们来观察其写法:

>>> word = 'Python'
>>> for ch in word: #出现了三个我们不认识的东西,for、ch还有in
	print(ch)
	
P
y
t
h
o
n

我们看到:

  1. for循环形状和前面学的if很像,for什么什么之后有一个冒号,然后另起一行缩进后书写。
  2. for循环的一般格式为:
for <变量> in <序列>:
    <缩进语块>

也就是说,for循环,实际是将一个序列(本例中,变量word所指向的字符串’Python’)中的元素,顺次赋值给一个变量(本例中 ch),然后对该变量执行缩进语块中的操作(本例中,print(ch))。

其中,变量ch只是一个名称(在这里我取的是character的首两字母),我们同样可以写成其他自己喜欢的变量名:

for letter in word:

其中,序列除了本例中的字符串外,还可以是列表、元组、集合以及我们前面学过的range()函数生成的整数序列等等。

 

  • 应用实例

初步理解for循环之后,我们来看一些实际应用的例子来加深理解:

for循环与if语句嵌套:假设我们要写一个程序——用户输入一个英文单词,程序逐行打印出该单词中所有的元音字母:

word = input('请输入一个英文单词:') #由于input()返回的是字符串,因此不需eval()

for ch in word:
    if ch in 'aeiouAEIOU': #英语中,元音字母有且仅有五个
        print(ch) #注意这一行再次进行了缩进

我们看到,在这个例子中,我们的缩进语块部分从之前一个单一的print()扩展到了一个if条件语句,我们对变量word中的每个元素进行了一次“是否为元音字母”的判断,将判断结果为True的元素,进行了打印。其中,我们要特别注意正确使用缩进

 

计算数列乘积:假设我们有一个纯数字列表[4, -2.7, 8 ,666 ,9 , -7],我们要计算所有数字的乘积:

lst = [4, -2.7, 8 ,666 ,9 , -7]
result = 1 #将整数1赋值给变量result,用来储存乘积

for num in lst:
    result = result * num #将result与num的乘积重新赋值给result
    
print(result) #注意本行的缩进,是在for循环结束之后才打印,并非每循环一次都打印

尤其注意理解第四行的用法:我们讲过,Python会先计算赋值号右边的结果,再赋值给左侧的变量。result最初是整数1,在第一次循环中,result与列表中第一个数4相乘,乘积4被重新赋值给result,此时result指向整数4。在下一个循环中,便是result指向的4与序列中的第二个数-2.7相乘了。以此类推。

 

利用索引循环*:假设我们有一个列表[1, 2, 3, 4, 5],我们使用如下循环:

>>> lst = [1, 2, 3, 4, 5]
>>> for num in lst:
	print(num)
	
1
2
3
4
5

通过上面的讲解,这个循环相信大家都很容易理解了。下面,我们介绍另一种方式来循环这个列表:

>>> for x in range(len(lst)):
	print(lst[x])
	
1
2
3
4
5

我们发现:我们首先利用len(lst)计算出了列表长度;
然后,利用这个长度生成了一个整数序列range(len(lst));
接着,我们用for循环将这个数列中的数依次赋值给x;
最后,我们打印出列表中索引号为x的元素lst[x]。

为什么要使用这种更复杂的方法来循环呢?

我们假设要写一个程序,判断一个列表[81267,  844690,  877845,  804469,  897759,  897454,  897674,  896749,  895657] 中的数字是不是按照从大到小排序的:

lst = [81267, 844690, 877845, 804469, 897759, 897454, 897674, 896749, 895657]
for num in lst:
     #_(:з」∠)_  写不下去了,因为我们没法用这种循环比较前后两个元素

这时,我们就不得不使用索引号来循环这个列表:

lst = [81267, 844690, 877845, 804469, 897759, 897454, 897674, 896749, 895657]

for x in range(len(lst)-1): #思考一下为什么是len(lst)-1
    if lst[x+1] < lst[x]: #判断是否存在任意索引为x+1的数小于索引为x的数
        print('表中第', x, '个数大于第', x+1, '个数', sep = '')

由于我们还学习到函数,上面这段代码功能不完善,但是通过这个例子,我们应该认识到,有的时候,通过索引号来进行循环是有意义的。

 

  • 本节练习

使用for循环逐行打印出列表[1, 64, 376, 881, 97, 108, 4, 67]中的奇数。

看答案

>>> lst = [1, 64, 376, 881, 97, 108, 4, 67]
>>> for num in lst:
	if num%2 ==1:
            print(num)
		
1
881
97
67

酱哦

 

已知以下两个列表:

ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
classes = ['红桃', '黑桃', '方块', '梅花']

利用for循环生成一个新的列表deck,包含一副去除大小王的扑克牌中所有元素。

看答案

>>> ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
>>> classes = ['红桃', '黑桃', '方块', '梅花'] 
>>> deck = []
>>> for r in ranks:
	for c in classes:
		deck.append(c+r)

		
>>> deck
['红桃A', '黑桃A', '方块A', '梅花A', '红桃2', '黑桃2', '方块2', '梅花2', '红桃3', '黑桃3', '方块3', '梅花3', '红桃4', '黑桃4', '方块4', '梅花4', '红桃5', '黑桃5', '方块5', '梅花5', '红桃6', '黑桃6', '方块6', '梅花6', '红桃7', '黑桃7', '方块7', '梅花7', '红桃8', '黑桃8', '方块8', '梅花8', '红桃9', '黑桃9', '方块9', '梅花9', '红桃10', '黑桃10', '方块10', '梅花10', '红桃J', '黑桃J', '方块J', '梅花J', '红桃Q', '黑桃Q', '方块Q', '梅花Q', '红桃K', '黑桃K', '方块K', '梅花K']

酱哦

 

【选做】写一个程序,让用户输入一个英文单词,并将其中的所有元音字母变成大写

看答案

word = input('请输入一个英文单词:')
new_word = word

for i in range(len(word)):
    if word[i] in 'aeiouAEIOU':
        new_word = new_word.replace(word[i], word[i].upper())

print(new_word)

酱哦

 

如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

使用if语句控制流程

在文本编辑器里随便写点东西,然后点击关闭,程序会自动弹出一个框,询问用户是否保存这个文件。如果选了是,计算机就会储存这个文件;如果选择否,则放弃保存;如果选择取消,就会回到编辑界面。我们遇到的程序,都会根据用户不同的操作,返回不同的结果,我们称之为流程控制。我们首先来学习最简单的条件流程控制

 

  • if语句

我们在Python中,可以用if语句,来实现这种如果……就……的操作。
前一段时间联合国官微说15-24岁的人属于青年,那么让我们来写一个程序,用户输入其年龄,然后程序来判断用户为少年、青年、宝宝(大雾..还是老年吧~
首先,我们仍然使用input()的方法,引导用户输入自己的年龄,并将其赋值给变量age:

age = eval(input('请输入您的年龄:'))

下面,我们先口头对需要判断的条件做一个梳理:
如果age < 15,那么用户属于’少年’;
如果15<= age <= 24,那么用户属于’青年’;
如果24 < age < 60,那么用户属于’宝宝’;
如果age >= 60,那么用户属于’老年’。

Python中,我们用if(如果),elif(又如果),else(其他)来实现根据不同条件控制程序流程,首先观察:

age = eval(input('请输入您的年龄:'))
if 0 < age < 15:
    print('您是位少年~')
elif 15 <= age <= 24:
    print('您是位青年~')
elif 24 < age < 60:
    print('您是个宝宝')
elif age >= 60:
    print('您是老年人~')

我们发现,书写格式为:在if或elif之后写上需要判断的条件——输入冒号——另起一行——按下键盘TAB键(大写锁定的上方)对新行进行缩进——写出当条件为True时需要执行的命令。

注意,使用TAB键缩进后,我们按下回车另起一行,光标将自动延续上一行的缩进。如果此时if或者elif控制的内容已经写完,我们需要按下backspace(Mac键盘的delete)来取消缩进。

让我们首先保存这个文件,然后按下F5运行测试一下,如果一切正常~ 那么你已经学会了如何运用条件判断来控制Python运行的流程~ 下面,我们来讨论几个问题:

 

  • 使用else语句

我们假设有人在程序里面输入了一个负数:

请输入您的年龄:-233
您是位少年~

这显然不太合理。我们还有一个else语句,用以控制if和elif判断条件之外的情况——else语句必须写在同一组if和elif的后面,并且只能有一个else。其写法很简单,观察下面“改进版”程序:

age = eval(input('请输入您的年龄:'))
if 0 < age < 15:
    print('您是位少年~')
elif 15 <= age <= 24:
    print('您是位青年~')
elif 24 < age < 60:
    print('您是个宝宝')
elif age >= 60:
    print('您是老年人~')
else:
    print('您输入的年龄有误')

我们对这个文件进行保存,然后按F5进行测试:

请输入您的年龄:-666
您输入的年龄有误

 

  • 程序的逻辑

这两年数学高考中都会出现流程图这样的考题,实际上,对应我们上面写的Python程序,也是有一个运行的流程的,现在我们来具体观察这个流程:

age = eval(input('请输入您的年龄:'))
if 0 < age < 15:
    print('您是位少年~')
elif 15 <= age <= 24:
    print('您是位青年~')
elif 24 < age < 60:
    print('您是个宝宝')
elif age >= 60:
    print('您是老年人~')
else:
    print('您输入的年龄有误')

在这个程序中,第二、四、六、八、十行行分别是五个条件——其中,第二行的条件由if引导,四、六、八行由elif引导,第十行由else引导。

在Python中,程序首先按照代码行数的顺序运行

当碰见if语句,程序会检查if之后的条件是否为True,如果成立,那么Python开始运行if之后有缩进的语句,(也就是开头我们按了TAB键的语句),同时,Python会直接跳过if后续的所有elif、else语句包括elif、else语句下方缩进的内容

如果程序检查到if之后的条件为False,那么if下方缩进的所有语句,将直接被跳过,此时,程序开始按照行顺序检查第一个elif之后的条件是否成立,同样,elif之后的条件成立,则执行对应的命令,并跳过其余的elif、else语句包括其余elif、else下方缩进的内容,以此类推。

最后,只有当所有的if与elif条件检查均为False时,Python才会执行else下方的命令。

有的小伙伴会问啦,那看样子if和elif功能是一样的啊,那为什么不将程序写成:

age = eval(input('请输入您的年龄:'))
if 0 < age < 15:
    print('您是位少年~')
if 15 <= age <= 24:
    print('您是位青年~')
if 24 < age < 60:
    print('您是个宝宝')
if age >= 60:
    print('您是老年人~')
else:
    print('您输入的年龄有误')

这是因为,当我们采用elif写法的时候,如果Python判断开头的if条件为True,那么下方所有的elif会被跳过。而当我们全都写作if的时候,即便第一个if已经判断为Ture,Python依然会检查第二个、第三个 …… if后面的条件。在我们这个例子中,这是没有必要的,因此这给程序增加了不必要的运算,降低了运行速度。

 

  • 关于缩进

在Python中,规范使用缩进是很重要的,对比以下两段代码:

if age > 60:
    print('您是老年人')
    print('再见')
if age > 60:
    print('您是老年人')
print('再见')

在第一段中,print(‘再见’)相对if条件句有缩进,因此,只有当if条件为True的时候,程序才会打印“再见”。
在第二段中,print(‘再见’)相对if条件句无缩进,因此,Python将在if条件句执行完毕之后,打印“再见”。

学习到后期,我们在一个程序中会出现很多的缩进语块。有个笑话讲:问:”学习Python需要准备什么呀?“答:“需要一本教材、一台计算机、一个游标卡尺。”就是说后期代码写的很长的时候,如果教材翻页了,你就需要用尺子去量一量每句代码到底做了多少次缩进(掩面。。。

在我们使用的文本编辑器中,按下TAB键,会自动完成一次缩进,默认为四个半角空格。本节我们碰到的只需缩进一次,后期会有多次缩进的情况。因此,我们在书写代码时,不要手动打空格,统一使用TAB键进行缩进。

 

  • 本节练习

BMI指数,是用体重(公斤)除以身高(米)的平方得出的数字,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。请写一个程序,让用户输入体重(kg)、身高(m),程序按照下表判断并打印其胖瘦程度:

BMI

体型

18.5(含)以下

偏瘦

18.5(不含)到24(不含)

正常

24(含)到28(不含)

超重

28(含)以上

肥胖

看答案

weight = eval(input('请输入您的体重(单位:公斤):'))
hight = eval(input('请输入您的身高(单位:米):'))
bmi = weight / (hight**2)

if 0 < bmi <= 18.5:
    print('您的体型偏瘦')
elif 18.5 < bmi < 24:
    print('您的体型正常')
elif 24 <= bmi < 28:
    print('您的体型超重')
elif bmi >= 28:
    print('您的体型肥胖')
else:
    print('您输入的身高或体重有误')

酱哦


如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

写第一个Python程序

 

激不激动?!

 

咳咳。。。这一节我们来写一个简单的程序,熟悉一些基本的书写规则

之前说过,写程序需要使用纯文本编辑器,大家可以使用IDLE自带的,也可以下载心仪的其他编辑器。只要点击IDLE左上角的File,单击New File就打开了一个空白的纯文本(Ctrl+N也行)。

让我们写一个程序:用户输入自己的名字以后,界面上显示出:“欢迎你,xxx”。

我们先利用input()引导用户输入自己的名字,然后将这个名字存放在变量name中:

name = input('请输入您的名字:')

接着,我们要打印出“欢迎你,xxx”,其中xxx用name这个变量指代的对象替换。在Python中,每写一条命令需要另起一行,按下回车输入print()命令:

name = input('请输入您的名字:')
print('欢迎你,', name, sep = '')

我们在print()的最后加上sep=”,这样’欢迎你,’和人名之间就没有多余的空格。

好了,这样我们就写完了所有的步骤。接着,我们要保存这个文件,左上角File-Save(Ctrl+S)。我们会发现,保存的文件类型是.py,也就是说这是一个我们自定义的模块(只不过我们这个模块里面没有函数,只有两行简单的代码)。

保存好之后,我们按下F5,IDLE就开始运行我们刚写好的这个.py模块,输入你的名字试试呗。

你说这个好像没什么用…? 万丈高楼平地起嘛。试试这个:

 

  • 本节练习

写一个程序,让用户输入当前的温度(摄氏度)后,显示对应的华氏度。注: = (οF – 32) / 1.8

看答案

temp_C = eval(input('请输入现在的摄氏温度:'))
temp_F = temp_C * 1.8 + 32
print('当前温度为华氏', temp_F, '度', sep = '')

酱哦


如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

Python内建函数与模块

  • 常用内建函数

在前面的学习中,我们接触了诸如print(), abs()这样的函数————只要打开Python交互界面就可以直接使用。这些函数被称作Python内建函数(built in functions)。在这一章节,我们首进一步认识几个内建函数:

print()函数:我们可以用print()函数打印多个内容,例如:

>>> age = 15
>>> print('我今年',age,'岁了')
我今年 15 岁了

我们会发现15的前后都有空格,这是因为,print()默认把打印的多个元素之间用空格隔开了,我们可以更改分隔元素的符号,例如上一例中,我们希望print()用空字符串”来分隔而不是空格’ ‘:

>>> print('我今年', age, '岁了', sep = '')
我今年15岁了

注意sep要写在需要打印元素的后面,不能穿插在需要打印元素的中间。当然,你也可以用其他字符花式分隔多个被打印元素:

>>> print('我今年', age, '岁了', sep = '哟哟')
我今年哟哟15哟哟岁了

range()函数:可以返回一个整数序列,先观察下面语句:

>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(1, 5))
[1, 2, 3, 4]
>>> list(range(1, 5, 2))
[1, 3]

注意几点:
1. range(x, y)得到的是x开头,y-1结尾的整数序列,如果x为0可以不写
2. range(x, y, z)得到的是x开头,公差为z的等差整数序列,序列中最大数不大于y,如果z为1可以不写
3. range()函数返回的不是一个列表!上述的例子使用了list()将结果强制转换为列表方便大家看清。试试直接输入type(range(5))会返回什么
4. 现在你返回到上一章第7节的最后,是不是有新发现啦~

input()函数:可以让用户输入一些信息,例如:

>>> name = input('请输入你的名字:')
请输入你的名字:欧耶
>>> name
'欧耶'

在input后面的括号内,我们可以自由输入一个字符串,作为用户输入内容的提示语。当我们写完第一行按下回车的时候,Python就执行了input()这个函数,并出现了一行可以互动的语句,我们可以在该行输入任意信息,最后,我们输入的信息被赋值给了变量name。

观察下面的程序:

>>> num = input('请输入一个数字:')
请输入一个数字:233
>>> num + 1
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in 
    num + 1
TypeError: must be str, not int
>>> num
'233'
>>> type(num)
<class 'str'>

我们发现,当使用input()函数时,不论用户输入什么信息,都被Python自动转化成了字符串(str)。要记住,input()函数返回的结果一定是一个字符串。那么,有没有办法让用户输入的字符串变成数字呢?

eval()函数:该函数的括号内可以填入一个字符串,Python将根据这个字符串的内容,自动转换数据类型:

>>> num = eval(input('请输入一个数字:'))
请输入一个数字:233
>>> num + 1
234

我们知道input()函数必然返回一个字符串,因此我们可以将input()填在eval()函数的括号中,Python自动将字符串中的内容转换成了整数。

有的小伙伴就会问了,那可不可以用之前学过的强制转换类型来实现字符串到整数的转换呢?答案是可以的,如果我们明确知道要转换的类型,可以直接使用强制转换:

>>> num = int(input('请输入一个数字:'))
请输入一个数字:233
>>> type(num)
<class 'int'>

在这个字符串’233’转换到整数233的例子中,两种方法都一样简单可行。学习到后期我们会发现,eval()函数还能自动判断一些更复杂的字符串,并转换相应类型。

 

  • 什么是Python模块

当使用abs()函数时,只要在括号内输入一个数,就会得到它的绝对值。但是我们知道,从数学角度来说,要计算一个数的绝对值,我们是要分情况讨论的:当x >= 0, |x| = x;当x < 0, |x| = -x。也就是说我们在使用abs()函数的同时,这个函数代替我们完成了这一系列判断与计算的过程 —— 那么这些过程都写在哪里呢?还有print(), eval()和我们还没学到的函数,它们的过程是什么?都写在哪里呢?

在Python中,函数的定义被写在一个个后缀为.py的文件中。这些.py文件,被称为Python的模块(modules)。 之所以输入abs(-1)我们可以得到1这个结果,是因为Python加载了一个模块,在这个模块里,发明Python的大神已经写好了abs()遵守:当x >= 0, |x| = x;当x < 0, |x| = -x这个规则。

类似于abs(),print(),eval()这些内建函数,它们具体在.py文件里面具体是如何定义的,我们目前不用知道,我们只用知道它们有什么功能即可。这些内建函数所在的模块,Python是自动加载的,打开Python就能使用。

 

  • 使用其他Python模块

我们安装Python之后,Python自带一个标准库(Python Standard Library),这个标准库里面有大大小小200多个模块可以供我们使用,网上还有数不清的Python模块可以下载。想使用这些模块,我们需要手动加载它们。这里我们介绍两个非常常用的:

math模块:顾名思义,这个模块内定义了大量和数学有关的函数。使用该模块,我们首先需要输入:

>>> import math

回车之后,如果没有报错,那么就成功引入了math模块。math模块中定义了N多函数,可以输入help(math)查看。列举两例:sqrt()开平方根;log(x,y)以y为底x的对数。要想使用这些函数,函数名字前必须写上math.

>>> math.sqrt(4)
2.0
>>> sqrt(4) #如果不写math.就会这样
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in 
    sqrt(4)
NameError: name 'sqrt' is not defined

 

random模块:这是一个用来生成随机数的模块。与math一样,我们首先要加载random模块,然后可以用help(random)查看该模块中所有的函数,这里我们只介绍两个:

>>> import random

randrange()函数:这个函数可以理解为random(随机)和range()的组合体,括号内填写的内容和上面我们说的range()函数规则一样;最终该函数将在生成的整数序列里面随机返回一个数。例如,在1,2,3,4四个整数中随机抽取一个:

>>> random.randrange(1, 5)
3
>>> random.randrange(1, 5)
2
>>> random.randrange(1, 5)
3

shuffle()函数,这个函数可以用于随机打乱一个列表的顺序:

>>> import random
>>> lst = [1, 2, 3, 4, 5, 6]
>>> random.shuffle(lst)
>>> lst
[6, 4, 3, 1, 5, 2]
>>> random.shuffle(lst)
>>> lst
[6, 3, 5, 1, 4, 2]

 

如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

命令式编程引言

上一章中,我们学习的都是如何执行单条Python命令。在这一章中,我们将学习如何编写Python程序使其有序地执行多条命令。我们会学习如何调用Python内部自带的函数、模块;我们也会学习在程序运行过程中如何用条件来控制程序流程;我们还会学习如何建立自己的函数与模块来封装复杂的功能。

随着我们写的程序越来越长,我们将更多地采用“注释”的方式,在程序内部对程序进行讲解,如果你还记得,在上一章第六节出现过这样的代码:

>>> num_1 = {1,2}
>>> num_2 = {1,2,3}
>>> num_1 | num_2
{1, 2, 3}
>>> num_1 & num_2
{1, 2}
>>> num_1 | num_2 #并集
{1, 2, 3}
>>> num_1 & num_2 #交集
{1, 2}
>>> num_1 <= num_2 #num_1包含于num_2则为True,反之为False True
>>> num_1 < num_2 #num_1真包含于num_2则为True,反之为False

下面的几行中,出现了一个井号#,后面跟了一串解释的文字,这称为注释。Python不会执行#之后的内容,但是别人在看你的程序的时候,可以读到你写的注释。

信不信由你,学完本章就可以写游戏了呢!(。・∀・)ノ゛

 

如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

列表的高级方法*

  • 列表方法

在Python中,我们还可以对一个列表进行以下操作:

在列表末尾添加新元素————我们可以用append()给列表添加新元素:

>>> list_1 = [1,2,3]
>>> list_1.append(4)
>>> list_1
[1, 2, 3, 4]

 

在特定位置添加新元素————我们可以用insert()给列表添加新元素:

>>> list_2 = [1,2,4]
>>> list_2.insert(2,3)
>>> list_2
[1, 2, 3, 4]

我们注意到,insert()的括号内需要首先填入我们希望新元素所在位置的索引号,再填入希望插入的元素。

 

删除列表最后一个元素————我们可以用pop()完成:

>>> list_3 = [1,2,3]
>>> list_3.pop()
3
>>> list_3
[1, 2]

我们注意到,Python在执行pop()后会首先返回被删除的元素。

 

删除某元素————我们可以用remove()完成:

>>> list_4 = [1,2,1,2,3]
>>> list_4.remove(2)
>>> list_4
[1, 1, 2, 3]

我们注意到,remove后面的括号内填写的是需要删除的元素。并且,如果列表中有多个被指定删除的元素,Python只会删除第一个。

 

查找某元素————我们可以用index()完成:

>>> list_5 = [6, 6, 6, 2, 3, 3]
>>> list_5.index(6)
0
>>> list_5.index(3)
4

我们注意到,如果被查找的元素在列表中有多个,Python只会返回该元素首次出现的位置索引。

 

元素计数————和字符串类似,我们可以用count()完成:

>>> list_5 = ['dog', 'dog', 'cat', 'elephant']
>>> list_5.count('dog')
2

 

列表排序————我们可以用reverse()将列表倒序:

>>> list_6=[1, 7, 4, 6, 2]
>>> list_6.reverse()
>>> list_6
[2, 6, 4, 7, 1]
>>> 

我们注意到,这是列表顺序的倒序,和数字大小无关。我们还可以用sort()让列表根据数字大小、字母顺序等规则排序:

>>> list_6.sort()
>>> list_6
[1, 2, 4, 6, 7]
>>> list_7 = ['alpha', 'zelda', 'peter', 'boy']
>>> list_7.sort()
>>> list_7
['alpha', 'boy', 'peter', 'zelda']

要是列表里又有数字又有字母,甚至还有其他数据类型的对象,那么程序就报错啦。

 

  • 列表切片

和上一节字符串的切片类似,我们可以队列表进行切片:

>>> list_8 = [1, 2, 3]
>>> list_8[1:]
[2, 3]

注意,列表后面跟索引号,返回的是列表中的一个元素;列表切片,返回的则是一个列表。

 

  • 又见可变对象

上一节里,我们看到了字符串作用方法之后,本身并没有发生改变,这是由于字符串是不可变对象。这一节讲的列表,却是一种可变对象:

>>> lst = [1, 2, 3]
>>> lst
[1, 2, 3]
>>> lst.append(5)
>>> lst
[1, 2, 3, 5]
>>> lst.insert(3, 4)
>>> lst
[1, 2, 3, 4, 5]

我们发现,我们并没有给lst这个变量重新赋值,然鹅它所指向的对象————那个“坑”————里面的东西在不停地发生变化。这说明,列表真的是可变对象,所有的方法直接修改了最开始创建的列表。

正因如此,我们可以用索引和赋值的方法,直接改变列表中的元素:

>>> list_7 = ['alpha', 'zelda', 'peter', 'boy']
>>> list_7[0] = 'beta'
>>> list_7
['beta', 'zelda', 'peter', 'boy']

 


列表的操作方法就这些了吗?No骚年!这些是常用的,想知道所有的列表操作方法吗!在IDLE里面输入help(list)试试~

 

  • 本节练习

将列表[28, 6, 99, 1, 46, 90, 17, 4, 19, 108, 71, 66, 24, 5, 17, 36, 92, 2, 64, 82, ‘捣乱’, 3, 11, 75, 34, 62, 98]中不是数字的元素去掉,并将列表按照数字从大到小排序。

看答案

>>> lst = [28, 6, 99, 1, 46, 90, 17, 4, 19, 108, 71, 66, 24, 5, 17, 36, 92, 2, 64, 82, '捣乱', 3, 11, 75, 34, 62, 98]
>>> lst.remove('捣乱')
>>> lst.sort()
>>> lst.reverse()
>>> lst
[108, 99, 98, 92, 90, 82, 75, 71, 66, 64, 62, 46, 36, 34, 28, 24, 19, 17, 17, 11, 6, 5, 4, 3, 2, 1]

酱哦


如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写~

字符串的高级方法*

  • 字符串方法

前面的章节我们讲了字符串的一些简单方法(相加、与整数相乘和索引)。现在,我们来看Python还可以对字符串执行哪些有用的操作。

大小写转换————我们可以利用capitalize()将字符串中的第一个字符转换为大写(前提是第一个字符是一个字母),其余字母转换为小写:

>>> s_1 = 'hello, iT\'s mE'
>>> s_1.capitalize()
"Hello, it's me"

也可以利用upper()将所有字母转化为大写,或者lower()将所有字母转化为小写:

>>> s_1.upper()
"HELLO, IT'S ME"
>>> s_1.lower()
"hello, it's me"

 

空格消除————我们可以利用lstrip()、rstrip()和strip()来消除字符串最左端、最右端或者两端的空格:

>>> s_2 = '   example   '
>>> s_2.lstrip()
'example   '
>>> s_2.rstrip()
'   example'
>>> s_2.strip()
'example'

 

查找特定字符————我们可以利用find()完成:

>>> s_3 = 'boomshakalaka!'
>>> s_3.find('a')
6
>>> s_3.find('!')
13

我们注意到,虽然字符’a’在这个字符串里面出现了四次,但是find()只返回’a’首次出现位置的索引号。
字符计数————我们可以用count()来数数特定字符在字符串中出现了几次:

>>> s_3.count('ka')
2
>>> s_3.count('a')
4

 

字符更替————我们可以用replace()来替换掉字符串中的特定字符:

>>> s_3.replace('boom','bang')
'bangshakalaka!'

我们注意到,替换的时候,被替换的字符写在逗号左边,新字符写在逗号右边。

 

字符串分割————我们可以用split()以特定字符为分节符,分割字符串,然后获得一个列表,这个列表里面的元素是分割开来的字符串:

>>> s_4 = 'I am learning Python!'
>>> s_4.split()
['I', 'am', 'learning', 'Python!']
>>> s_5 = 'Peter, Alicia, Brian, Sofia'
>>> s_5.split(', ')
['Peter', 'Alicia', 'Brian', 'Sofia']

我们注意到,如果直接使用split(),那么Python就把原来字符串中的所有空格当做分节符,把字符串分成了若干个新的字符串,并把它们全放到了列表里面。我们也可以在split()的括号内,自定义一个分节符,例如s_5中,我们用一个逗号和一个空格’, ‘这个字符串来分界,就可以把所有的人名放到一个列表里了。

提示:当直接使用split()的时候,如果两个字符之间有多个空格,Python会将其识别为一个分隔符。例如,字符串’a b’和字符串’a             b’尽管中间空格数量不同,但使用默认split()分割的结果是一样的。

 

映射转换*————有点费解的一个功能,但是很好用很常用,以后常回来看看。我们可以先通过str.maketrans()建立一个映射,然后利用translate()和这个映射去转换其他字符串,我们先看例子:

>>> s_6 = 'This_is@a-very!weird=sentence.'
>>> table = str.maketrans('_@-!=',' '*5)
>>> s_6.translate(table)
'This is a very weird sentence.'

我们看到,第一行中的s_6是一个奇怪的句子,本来应该空格的地方却是一堆符号。

第二行,我们利用str.maketrans()建立了一个映射,我们把本该是空格位置的符号写成一个字符串放在括号内逗号左边,逗号右边则是一个由5个空格组成的字符串,意思是说,我们把逗号左边的字符串中的每个字符与逗号右边字符串中的每个字符一一对应起来。接着,我们把这个一一对应(映射)关系存放在table这个变量里面。

第三行,我们对原先奇怪的句子s_6实施translate()这个操作,translate的依据,则是我们刚才建立的映射table。

第四行,返回结果,我们将句子中所有的符号,转换成了符号对应的字符————空格。

这里我们重申一点,空格也是一个字符,’ ‘和空字符串”区别大大滴有。

 

  • 字符串切片

之前我们讲过字符串索引,实际上利用索引号,我们还可以对字符串进行更复杂的操作————切片。让我们先创建一个简单的字符串:

>>> s_7 = 'hello'
>>> s_7[0]
'h'

现在,我们在索引的中括号里面加入一个冒号和一个新的索引号:

>>> s_7 = 'hello'
>>> s_7[0:2]
'he'

我们看到,Python这时候返回了字符串的前两个字符组成的新字符串。也就是说,一个字符串s,如果我们对他进行s[x:y]的操作,Python将返回这个字符串索引号为x的字符开头,索引号为y-1的字符结尾的新字符串,这称为切片(slicing)。

如果切片开始的位置是字符串的首位,或者切片结束的位置是字符串的末位,我们可以如下简写:

>>> s_7[:3]
'hel'
>>> s_7[-3:]
'llo'

 

  • 又见不可变对象

在本章第四节中,我们初次接触了可变对象与不可变对象,你应该还对那个萝卜西瓜和花生的故事有点印象。学习了字符串的高级方法之后,我们可以对字符串这个“不可变对象”有更深的认识。

任意创建一个字符串并对其进行任意个我们上面讲的字符串方法操作,例如:

>>> string = 'whatever this is   '
>>> string.strip()
'whatever this is'
>>> string
'whatever this is   '
>>> string.replace('whatever', 'haha')
'haha this is   '
>>> string
'whatever this is   '
>>> string.capitalize()
'Whatever this is   '
>>> string
'whatever this is   '

我们发现,方法倒是奏效了,Python也返回了对应的结果,但是string这个变量所指的对象————那个“坑”————里面的东西没有发生变化。这说明,字符串真的是不可变对象,所有的方法所谓的改变、更替,实际上都是Python重新创建了一个新的字符串给我们。

那你会问,那上述新创建的三个字符串哪去了?嗯,我们没有用一个新的“坑”把它们装起来,所以现在找不到它们了。怎么样才能保存我们新生成的字符串呢?答案是用一个新的变量来装它们:

>>> new_string = string.capitalize()
>>> new_string
'Whatever this is   '
>>> string
'whatever this is   '

 


字符串的操作方法就这些了吗?No骚年!这些是常用的,想知道所有的字符串操作方法吗!在IDLE里面输入help(str)试试~

 

  • 本节练习

把这句话里每个人名作为一个元素,放进一个列表里,看看一共有几个名字:I have many girl friends: Capri, Amy, Lily, Wang, Sofia, Dora, Mia, Miley, Olivia, Brielle, Rue, Alice, Cora, Violet, Anna, Bella, Lucy, Lydia, Ella, Jean, Jane, Chole, Ada, Julie, Jackie, Gemma, Eloid, Zelda, Cecelia, Rose, Rebecca, Louisa, Sammy, Jasmine, Allison, Morgan, Victoria, Claudia, Candice, Crystal, Rachel, Grace, Elizabeth, Mofy, Momoko, Angelica, Kelly, Sarah, Hannah, Tomoya, Molly!

看答案

>>> s = 'I have many girl friends: Capri, Amy, Lily, Wang, Sofia, Dora, Mia, Miley, Olivia, Brielle, Rue, Alice, Cora, Violet, Anna, Bella, Lucy, Lydia, Ella, Jean, Jane, Chole, Ada, Julie, Jackie, Gemma, Eloid, Zelda, Cecelia, Rose, Rebecca, Louisa, Sammy, Jasmine, Allison, Morgan, Victoria, Claudia, Candice, Crystal, Rachel, Grace, Elizabeth, Mofy, Momoko, Angelica, Kelly, Sarah, Hannah, Tomoya, Molly!'
>>> new_s = s[s.find('C'):-1]
>>> name_list = new_s.split(', ')
>>> name_list
['Capri', 'Amy', 'Lily', 'Wang', 'Sofia', 'Dora', 'Mia', 'Miley', 'Olivia', 'Brielle', 'Rue', 'Alice', 'Cora', 'Violet', 'Anna', 'Bella', 'Lucy', 'Lydia', 'Ella', 'Jean', 'Jane', 'Chole', 'Ada', 'Julie', 'Jackie', 'Gemma', 'Eloid', 'Zelda', 'Cecelia', 'Rose', 'Rebecca', 'Louisa', 'Sammy', 'Jasmine', 'Allison', 'Morgan', 'Victoria', 'Claudia', 'Candice', 'Crystal', 'Rachel', 'Grace', 'Elizabeth', 'Mofy', 'Momoko', 'Angelica', 'Kelly', 'Sarah', 'Hannah', 'Tomoya', 'Molly']
>>> len(name_list)
51

酱哦

请用切片的方法将字符串:
‘i9rhasiou23090_234rhioasdcvoif2903j69spgjanodvp!dfo02uiopvae+890p23uivah@u80q23i9o0asd’
的后21个字符切片为新的字符串。

看答案

>>> s = 'i9rhasiou23090_234rhioasdcvoif2903j69!dfo02uiopvae+890p23uivah@u80q23i9o0asd'
>>> s[-21:]
'23uivah@u80q23i9o0asd'

酱哦

【选做】请将余光中先生的现代诗《算命瞎子》节选中所有标点转换为换行:

凄凉的胡琴拉长了下午,偏街小巷不见个主顾;他又抱胡琴向黄昏诉苦:空走一天只赚到孤独!

提示


转义字符\后加n可以实现对字符串换行。例如

>>> print('hello\nbaby')
hello
baby

再想想


看答案

>>> poem = '凄凉的胡琴拉长了下午,偏街小巷不见个主顾;他又抱胡琴向黄昏诉苦:空走一天只赚到孤独!'
>>> tabel = str.maketrans(',:;!', '\n'*4)
>>> format_poem = poem.translate(table)
>>> print(format_poem)
凄凉的胡琴拉长了下午
偏街小巷不见个主顾
他又抱胡琴向黄昏诉苦
空走一天只赚到孤独

酱哦


如果还有什么问题或者发现了文章的错误,欢迎给我留言!邮箱可以随便乱写 ~