python 写一个界面小程序

大家好,小编来为大家解答以下问题,python设计一个小程序,python编写一个小程序,现在让我们一起来看看吧!

大家好,给大家分享一下python考点总结,很多人还不知道这一点python源码库。下面详细解释一下。现在让我们来看看!

Source code download: 本文相关源码

写在前面:

一直奇怪某校几乎全校都要考python,却没什么人整理个知识点出来。Python知识点本来就碎,网上搜到的又很零散python艺术作品。个人码字整理不易,如有错误请在评论区友善讨论!

如果你对python或者编程没有提前做任何了解,这篇知识点会有点晦涩难懂。

这篇知识点并不能与python教材相提并论,是建立在其基础之上的。在阅读此知识点前请至少对数据类型、分支、循环、函数、python常用函数(print()、input()、eval()、type()等)、python语法有基本了解。

还是那句话,题目做不完的,这篇与其说是知识点汇总,倒更像是对不同题的内核考点以及处理思路,还有本人对编程的想法总结。对于非编程专业同学来说,后者会深一些。

目录

0.Python基本知识

1.Python保留字和变量名判断

2.关于进制转换的问题

3.关于数字类型以及abs函数的用法特例

4.复数结构浅析

5.python运算符以及运算机制

6.字符串比较浅析

7.字符串函数

8.字符串切片

9.字符串format函数

10.逻辑与、或的判别机制

11.分支结构浅析

12.循环结构浅析

13.异常处理浅析

14.列表、元组、字典、集合浅析

15.函数性质、参数机制浅析

16.变量的作用域问题:

17.python内置函数

0.Python基本知识

(1) Python是解释型语言、是脚本语言!运行的时候,每向电脑解释一行代码,电脑跑一步。C语言是编译型语言,在原理上不同!

(2)从速度上来说,Python的运行时间比C语言更长。可以粗浅地理解为:python是在C语言的基础上开发的,有一个转换成C语言代码的过程。

(此段看不懂可跳过)

Python也称C Python,由C语言开发而来。

C语言: 代码编译得到机器码,机器码在处理器上直接执行,每一条指令控制CPU工作。 Python语言:代码逐行解释得到字节码 ,虚拟机执行字节码并转换成机器码后在处理器上执行;

(3)由于Python是解释型语言,随解随用,因此移植性较好,适合在不同系统的电脑上运行。因为语法简单,其扩展丰富,多用于数据处理分析、机器学习、web开发领域。移植性强的弊端是与系统交互少,不触及底层,因此不适合作为系统软件的底层。

(4)Python源文件的后缀名为py。

(5)Python注释:一行用#号,一段的开始和末尾用三重单引号或三重双引号

1.Python保留字和变量名判断

导入模块用的:import、from、as

逻辑判断用的:if、else、elif

                         and、or、not

                         True、False(注意是大写!!)

                         in(检查列表、元组等集合中是否存在某个值)

                         is(测试两个变量是否相等)

创建方法用的:def、return

                         lambda(创建匿名函数)

                         yield(结束函数,返回生成器)

循环里的:for、while、continue、break

定义变量的:global(声明全局变量)、nonlocal(声明非局部变量)

处理异常的:try、except、finally、raise、with

其他不好分类的:assert(用于调试)、class(定义类)、del(删除对象)、None(表示null)、pass(一条什么都不做的语句)

变量名:

(1)变量名不能是保留字

(2)变量名只能以字母和下划线( _ )开头

(3)变量名不带有特殊符号如:!@#$%^&(-)<>?,.[ ]\|+-*/

小寄巧:判断哪个是错的,数字开头闭眼选;判断哪个是对的,带符号的不要选。

2.关于进制转换的问题

例题:

首先,0b开头表示二进制,0o开头表示八进制,0x开头表示十六进制。二进制中,一个数只能出现0和1,八进制中0到7,十六进制中,除了0到9这十个数以外,还用a到f表示10到15。

具体计算与十进制相同。一个十进制数,如123,等于:

3*10^0+2*10^1+1*10^2。二进制、八进制、十六进制同理。

三题具体计算过程如下(字丑勿喷):

特别地:

(1)对于0b、0o、0x的命名由来:

        二进制英文为binary,取首字母表示;八进制英文为octal,取首字母o表示;十六进制英文简写为hex,取其中的x表示。

 (2)进制间的转换:

八是二的三次方,十六是二的四次方,因此,八进制与十六进制都可转换成二进制计算:

 也可以计算出答案。

3.关于数字类型以及abs函数的用法特例

先不看题目。一般而言,abs这个函数表示取一个数的绝对值,0取0,负数取正、正数取正不多说。但是python引入了复数这个概念。表示一个复数,只需要在数的末尾加一个j即可。

而复数是没有绝对值的,故abs函数取得是它的模,对题中而言,计算结果为√((-3)^2+4^2) 等于5。

可为什么题中非得是5.0呢?它就不能省略掉0变成整数5吗?不能。这又引出了关于数字的数据类型:

Python中, 数字分为整型、浮点型,还有较特殊的两类:布尔型和复数型。

整型(int):就是整数,形如0、1、0b1010、0o1010、0x6f

浮点型(float):包含了所有实数,形如1.5、5.0、2.3e-2

复数类型(complex):包含了所有复数,形如-3+4j

布尔型(bool):True和False,表示真和假。这不是本节重点先不讨论。

题中对复数使用abs函数,在求模的过程中使用了开根号的运算(sqrt)。大家想,一个数的平方根,如果使用整型结构存储,是不是会很不友好呢?

比如求根号3和根号2,如果按整型输出,就只算到小数点前,那输出结果都是1。这显然是不符合逻辑的。因此,尽管有些数开根号下来能得到一个整数,但为了迁就那些得不到整数的,统一将输出结果的类型定为浮点型。所以题中是5.0,而不是5。

如果传一个整数进abs函数运算呢?

我们可以发现,它的类型是整型。

4.复数结构浅析

尽管有了关于复数类型的基本认识(指知道加j表示复数),但这题本人乍一看,也蒙了。经过仔细调试与搜索后,我大概讲讲我的理解,不一定完全对,但解决同类题应该没问题。

这题分两部分来看,左侧的1.23e-4是科学计数法的表示,相当于1.23*10^(-4)

当对一个变量这样赋值:

a = -3+4j

python就会判断这个变量为一个复数类型(complex),以复数类型的结构存储和运算。复数无非就是一个实数加一个虚数,实数是实部,虚数去掉j剩下的数是虚部。

请注意:实部和虚部都是实数!

接着,以我们非数学系的头脑想,实数和虚数的运算不就差了个-1嘛,有的地方虚数当实数算完了,补个-1就完事儿了。这么看,其实虚数与实数的运算十分类似。因此,把复数分成实部与虚部分别存储,运算时按不同规则运算是相当方便的。

当python发现一个变量是复数类型后,它又分别用real和imag两个属性存储该变量的实部与虚部(其实浮点型也有,只不过意义不大)。对于上面的a来说,a.real = -3.0,a.imag = 4.0:

又是奇怪的不省略0。但此时,相信大家已经有点理解了。个人浅薄的解释如下:实数包含了整数,而复数包含了实数,因此,对实部与虚部而言,应该用复数其下一级的类型存储,而非其下两级,如此,这种包含关系就更明显了。

现在再来看这题,就很简单了。5.67e+8j应该按复数类型存储,其实部为0.0,虚部为5.67e+8,调用其real属性,自然就是0。因此,这题的答案就是前面的1.23*10^(-4)。

补充:real属性并非是其前面1.23e-4+5.67e+8j整个整体的属性,仅仅是5.67e+8j的属性。

其等价为:

  5.python运算符以及运算机制

在C语言中,5/2的值是2,因为5和2都是整型数,相除得到的自然是整型。然而,python中不允许显式地定义变量类型赋值。此时,5/2得到实际值是2.5。

      C语言中不同类型数运算太麻烦,大家也只是想过个期末,这里就不展开讲。有兴趣的可以参考这个网址:c语言不同数据类型之间的运算(隐式转换、整型提升、强制类型转换、不同类型之间的运算)_c语言不同类型的数据之间运算_Moua的博客-CSDN博客

其中还涉及了字符与数字的对应关系。

      首先,在python中,我们在定义变量的时候不能事先控制变量的类型,只能由程序帮我们识别这个变量的具体类型。

此处是报错的

只能由程序判断具体类型为float

然而,这么处理之后,数字间运算就显得符合常理:一个数除以另一个数,除不尽本就应该保留小数。当然为方便起见,此处无论是否除得尽都保留了小数,因为在计算过程中被除数与除数都被转换成浮点型计算了:

但是,整除这个运算法则在许多场景下都非常有用,因此,python将它保留了,以“//”形式表达。比如:5//2的值是2,类型是int型。

此外,python用“x**y”表示x的y次方。至此,本题已可解答:答案为6。 注意:如果在使用整除运算时明确指出被除数或除数为浮点型,仍进行整除运算,只是结果转化为浮点型:

再来看一个有趣的运算:

连我在内,第一反应也是选True。但应该是False,这里涉及到底层运算、数字的转换与存储,仅简单说明。 当程序执行0.1+0.2这个运算时,0.1和0.2要先被转换成二进制数存进内存,再交由CPU运算。十进制的0.1和0.2转换成二进制后都是无限不循环小数,而程序不可能用无限的内存来存储一个变量,因此在某一位上截断了,这就导致两数在二进制运算后再转换成十进制时并不是0.3。精度越高,结果越逼近0.3。

同理,当小数位数过高时,程序也会忽略这一位小数,因为超过了规定的存储容量:

注意:大部分情况下,“ == ”两边的值都是相等的,变量所占内存达到的精度足够使这种误差忽略不计。

能找到的只有这两种情况是算不尽的。

6.字符串比较浅析

字符串,是“字符”的串。在许多编程语言中,字符串的比较都是依次比较每个字符的。如果某一位字符已经可以确定两边的大小关系,则停止比较,输出结果。如果一个字符串完了还没比较出来,那显然是更长的那个更大。这种设计就像英汉字典,如com就是是排在company前面的。

现在再来讨论在前面就能比出来的情况。这里我想稍微讲深一点,不想了解的同学只要知道:

空字符串<数字(0123...9)<大写字母(ABC...Z)<小写字母(abc...z)即可。

那这题的答案就很显然了:A左边没了右边还有,小于;B左边还有右边没了,大于;C左边空的右边有字符,小于;D的‘L’小于‘l’,小于;因此选B。

形如’1’、’2’、’a’、’b’这样的字符,计算机是不认识的,内存里也肯定不会直接存放这样的字符进去。在内存中,这些字符仍然是通过0和1的二进制码表示的。如果每个字符用8位二进制码表示的话,那就可以表示出2的8次方,128个字符。这样,在输入时把字符转换成对应的二进制码,输出时根据二进制码显示对应的字符就行了。而字符的比较,就是根据它们所对应的二进制码的大小来比较的。

最初,人们用0到127分别对应128个字符,其中包含十个阿拉伯数字、26个大写字母以及26个小写字母。顺序规定之后就没再改变了。这一套字符集被称作ASCII码。

后来,为了通信的需要,字符集扩充到256个,被称为IBM扩展字符集。IBM扩展字符集是对ASCII码的扩充。 再后来,随着各个国家接入互联网,字符集又不断扩充,逐渐形成今天成熟的“utf-8”、“gbk2312”等超大字符集。

IBM扩展字符集,前128个为ASCII码。其中第32位为空格,空格也是一个字符!

在python中,可以用chr()函数把ASCII码值转换为字符,用ord()函数把字符转换为ASCII码:

7.字符串函数

仅列出了属于字符串这个数据类型的常用、不易懂的函数。诸如startswith()、endswith()一看名称就理解的,以及不常用不常考的encode()、decode()没加。

如想全面了解,请阅读:

【python基础】python中常用字符串函数详解_python 字符串函数_非晚非晚的博客-CSDN博客

(1)字符串查询

find(str, __start, __end):查找子串str第一次出现的位置,如果找到则返回相应的索引,否则返回-1。__start和__end为可选参数,分别表示查询的开始索引与结束索引的后一位。

index(str, __start, __end):类似于find,只不过如果没找到会报异常。 其中find函数返回第一个字符p的索引,index函数因未找到字符s报错。

(2)大小写转换

upper( )、lower( ):将字符串中所有元素都转为大(小)写

swapcase( ):大写转为小写,小写转为大写。

capitalize( ):第一个单词大写,其余小写。

title( ):每个单词的第一次字符大写。

s = 'python Is NOT boring'
print(s.upper())
print(s.lower())
print(s.swapcase())
print(s.capitalize())
print(s.title())
>>> PYTHON IS NOT BORING
>>> python is not boring
>>> PYTHON iS not BORING
>>> Python is not boring
>>> Python Is Not Boring

(3)填充字符串

center(width, fillchar)、ljust(width, fillchar)、rjust(width, fillchar)

返回一个指定的宽度 width的字符串,fillchar为填充的字符,默认为空格。非填充字符分别显示在中间、最左侧、最右侧。

print ("hello world!".center(30, '*'))
print ("hello world!".ljust(30, '*'))
print ("hello world!".rjust(30, '*'))
>>> *********hello world!*********
>>> hello world!******************
>>> ******************hello world!

(4)字符串截断

split(seq=‘ ’, num=string.count(str)) 以 seq (默认空格)为分隔符截取字符串。如果 num 有指定值,则仅截取前(num+1)个子字符串。返回一个列表。num基本不用。

str = "a,b,c,d"
print (str.split(','))
>>> ['a', 'b', 'c', 'd']

(5)字符串替换

replace(old, new [, max])   将字符串中的old替换成new。如果指定max,则替换不超过 max 次。函数用得不多,更别提max了。

str = 'ppyytthhoonn'
print(str.replace('p','P'))
>>> PPyytthhoonn

(6)去除两端多余字符

strip(str)、lstrip(str)、rstrip(str):去掉左右两边的字符串str(默认为空格)。lstrip和rstrip分别去掉左和右侧字符串str。

str = '123python123'
print(str.strip('123'))
print(str.lstrip('123'))
print(str.rstrip('123'))
>>> python
>>> python123
>>> 123python

8.字符串切片

这道题考的是字符串的切片。字符串切片用” [ : ] “或” [ : : ] ”表示。

先看” [ : ] “:指定的区间属于“左闭右开”型:包含开始索引对应字符,不包含结束索引对应字符。

注意:0号索引表示第一个字符,1号表示第二个,以此类推。

str = '1234567890'
print(str[0:5])
>>> 12345

 这里取出了str字符串的第一到五个字符组成的字符串。

在python中,还允许使用负数索引,表示倒数第几个元素。-1就表示倒数第一个,以此类推。

str = '1234567890'
print(str[-5:-1])
>>> 6789

这里表示从倒数第五个到倒数第二个字符组成字符串。

此外,也可将正数与负数索引结合使用:

str = '1234567890'
print(str[3:-2])
>>> 45678

表示从正数第四个到倒数第三个

如果不指明索引,则开始索引默认为0,结束索引默认为最后一位对应索引的下一位(此处为10)。

str = '1234567890'
print(str[:5])
print(str[5:])
print(str[:])
>>> 12345
>>> 67890
>>> 1234567890

分别表示获取第一到第五个第六到最后一个整个字符串。

如果开始索引超出结束索引,则无法获取子字符串:

str = '1234567890'
print(str[6:-5])
>>> 

这里表示获取从正数第七个(7)到倒数第六个(5),显然是不合理的。

然而,仅使用一个冒号是无法实现隔字符取字符串或者倒序取字符串的,我们可以使用” [ : : ] ”,其中第三个值表示步长,默认为1,表示每取一个向前一步(即取下一个)。

如果要每取一个向前两步,就把步长改成2:

str = '1234567890'
print(str[::2])
>>> 13579

表示从第一个开始,每隔一个字符取一个字符。

当然,步长也可以是负的,表示每取一个向后n步。当步长为负时,开始索引应该大于等于结束索引才合理:

str = '1234567890'
print(str[::-1])
print(str[5:2:-1])
>>> 0987654321
>>> 654

我们先实现了倒序输出,其中省略的开始和结束索引自动改为最后一位对应索引的下一位和0。第二条取了从第六个开始到第三个前的字符串。

至此,我感觉已经讲的差不多了。回过头看看题目:一个’12345678’的字符串,切片为[1:-1:2],大家应该可以得到答案了吧。

9.字符串format函数

关于字符串的format函数,我觉得很麻烦,很枯燥,不好理解。仅总结下我遇到的几道题(差不多够了)。若想全面了解,可以看看这个网址内容:

python格式化输出之format用法 - 知乎

首先先明确, format函数功能大致是把字符串参数以特定格式添加到调用此方法的字符串中。有些功能使用+号连字符也能实现,但format函数,

下面看题: 第一组题:

这两道题放一起说,考的是format基本用法。

人们大概是很少在字符串使用大括号( {} )作为输出内容的,因此,format函数以一对大括号为标记,如果出现了这个标记,就说明这里得添加点别的东西。这“别的东西”呢,就写在了format的参数中。如果只写一对大括号,那就按顺序添加format括号里的字符串。写多了没事,反正不加。但写少会报错,原因等会再说。

'python{}.{}.{}'.format('3','6','8','64-bit')
>>> python3.6.8

 如果还在大括号中带数字编号,如“{0}”、“{1}”、“{2}”,就可以添加指定位置的字符串。

'python{2}.{0}.{1}'.format('6','8','3','64-bit')
>>> python3.6.8

format中改变了字符串的位置,但由于前面指定了输出顺序,还是可以正常输出。同样,写多了没事。

至此,这两题的答案已经明了,都是A。但对于输出顺序,我想再拓展一点(深,忙着复习的可跳过)。

在format函数中有两个参数:args和kwargs。可我刚才都输进去四个了,程序还是没有报错。这涉及到一种设计理念:对于一些函数,开发者难以预知用户将往里填入多少个参数。但根据函数功能,可以保证这些参数具有一定的相似性,如同一类型。我们看看源码:

这里的agrs前加了一个*,它其实表示一个元组。第一个函数的args用于接收用户输入的一组字符串。第二个是重载函数,其中的args用于接收各种数据类型组成一个元组,如上面第二题中的整型变量x, y, z。

因此,大括号内的数字其实是元组索引。如果用户没有指定,则按顺序添加;如果用户指定,则添加索引对应的字符串。如果大括号写多了,字符串写少了,那超过元组长度大括号的索引也就超出了元组最大索引,报错如下:

其中有四个大括号,三个字符串,报错为元组索引超出范围,也就可以理解了。

第二个参数kwargs前加了两个*号,表示一个字典,接收输入的一组键值对。使用举例:

print('my first name is {first_name}, second name is {second_name}'.format(
    first_name='Ghost', second_name='Kill'))
>>> 'my first_name is Ghost, second_name is Kill'

这里的两个参数分别以’first_name’: ‘Ghost’, ‘second_name’: ‘Kill’ 存入kwargs字典。比起使用+号连字符,语义上清晰多了。

第二组题:

再来说说format函数的字符串填充用法,有三种填充方式,与字符串函数里的ljust()、center()、rjust()类似:原字符串分别居左、居中、居右。书写格式就是冒号+待填充字符+原字符串对齐方式定义符+所需长度。几个注意点,待填充的只能是一个字符,不能是字符串,不写默认为空格填充;对齐方式定义符也分三种

<:左对齐;^:居中;>:右对齐。

如果原字符串超出所需长度,则按原字符串输出。至此,这题答案已经清楚了,选D。

尽管介绍了两种常用方法,可题目仍是层出不穷,全部答对也是不现实的。只能说知道的越多,越能接近正确答案。介绍两则特例:

 题中的所需长度好像是一个浮点数,理论上来说应该是不合理的吧,但题目既然这样出了,那应该是一种特殊用法。不慌,我们来排除看看:“>” 号肯定还是表示右对齐的,这样C、D就排除了。填充到最后的长度,总得和10或者6有关吧,而A选项长度为7,B选项长度为10,显然是B更合理一些。运行试试:

结果证明,我们猜的还挺准。可这到底是什么用法呢?我稍微调试几次看看。

print("{:@>10.6}".format('Fogggg'))
>>> @@@@Foggggg

 我先把字符串拉到6位长,确认了应该是显示十位(除非原字符串超出十位)。

print("{:@>10.6}".format('FogAndFog'))
>>> @@@@FogAnd

我又把字符串拉到9位,问题显现了,原字符串好像只能加载前六位。换句话说,有可能填充字符至少得占四位。

print("{:@>10.6}".format('FogAndFogAndFog'))
>>> @@@@FogAnd

这次我把字符串拉到12位,仍然只显示10位。至此这个“10.6”的意义已经清楚了:如果原字符串小于6位,则用填充字符补足到10位;如果超出6位,则只取前6位,剩余4位用填充字符补足。

print("{:@>10.7}".format('FogAndFogAndFog'))
>>> @@@FogAndF

换成“10.7”,输出也佐证了我们的推断。

题目很长,慢慢来看。看选项,大概是拿*号填充字符串a的意思,换行换了两次,那C肯定不对。居左和居右分不清,居中总知道吧,中间那行是居中的话,那只能选A了。

再仔细看看,字符串中又出现了0、1、2,应该是索引的意思,第一个0居然不用包起来,又长见识了。

10.逻辑与、或的判别机制

这题仔细一看,第一条判断中y是0却作为除数,应该是会报错的吧,但其实不然。亲自运行代码为证:

这就牵扯到逻辑判断的机制了:或的两端条件只要一端成立就成立,与的两端条件只要一端不成立就不成立。计算机也知道这个道理,于是在逻辑判断时会偷懒。代码中,当计算机发现 x > 5 为True之后,则直接执行print(‘Right’)语句,不再判断第二个条件。这样,就不会 抛出除数为0的异常了。如果我们把条件颠倒一下:

此处,程序运行至 x / y > 5时直接报错,不再往下运行。 同理,如果这里改成and并修改条件:

第一个条件x < 5为False,则直接跳出if,进入else的语句中。

以下为拓展内容:

这个特性得以保留,肯定是有其好处的。在实际开发中,比如从服务器接收一个字典。字典中一般会包含一个code状态码,用来表示响应状态。状态码不同值的含义可以事先约定好,如200表示获取字典成功,500表示获取失败。

取字典中的数据之前,先对字典做判空处理是很有必要的。如果字典为空,其中一定没有状态码;如果不为空,其中一定有状态码。

因此,状态码是否存在就与字典是否为空绑定了。

代码中,先判断字典是否为空,为空得到False,根据逻辑判断的特性程序会直接往下走,不再判断右侧字典中的状态码条件。否则字典中没有这个键,是会报错的。(在python中不会,JavaScript会,而且程序直接停止)

11.分支结构浅析

还是就题目论点吧,不考的记了还费脑子。

A、B放一起看,分支中的一支如果能够执行,一定是因为它的条件值为True,条件经过什么运算得到了这个True,分支结构并不关心。因此,不管是最普通的逻辑判断,还是函数返回的布尔值,甚至是变量的值都可以作为条件。

依次举例:

if (2 < 3):
print('如果没有输出那么我的电脑应该是坏了')
>>> 如果没有输出那么我的电脑应该是坏了

def test():
    return True
if test():
    print('函数也能作为判断条件')
>>> 函数也能作为判断条件

请注意,上面的代码是图片,每个条件都是真值才有输出。 这题的C选项的紧凑结构在没学之前我也不懂,但二分支结构和elif这个保留字同时出现,多少有些问题。D项就是多分支结构的意义:处理一个变量可能存在的多种情况,分配不同的解决办法,如成绩评价。C选项的话,我结合另一题来说:

这题我是一个个试出来的:

a = 4 if 2 < 3 else 5
print(a)
>>> 4

 Python对这个简便算法的处理语义更清晰:a等于4,如果2小于3的话,否则就等于5。格式是表达式1  if条件  else表达式2。

以下为拓展:在java中,这个三元运算符的表达就不一样:

int a = 3 < 5 ? 4 : 5;
.println(a);
>>> 4

结构是先条件再两个表达式,切勿弄混。

这题是从循环里扒出来的,先不看循环。第四行的条件中,只出现了“ x % 2 ”,并没有后续的判断。但既然题目这样写了就肯定能运行出来。这是一种省略写法,省略了后面的“ != 0 ”。上面以变量作为条件其实也是这种省略写法。如果写完整的话大致是这样:

 在实际开发中,省略的写法并不多用,我们还是更倾向于把条件写完整以加强可读性,用的多的地方主要还是判空(或判零):

def isEmpty(s):
    if not s:
        return True
    return False
s = ''
if (isEmpty(s)):
    print('空字符串')
>>> 空字符串

定义一个判空函数,如果NOT 这个字符串(不为空),意思就是这个字符串为空,就返回True,条件不成立(字符串非空)就默认返回True。

最后再补充一下:分支结构有三种,单分支结构仅出现if,二分支结构仅出现if和else,多分支结构中才有elif。

12.循环结构浅析

循环结构书上讲的已经很详细了,题目方面和前面说到的点都有联系,主要还是刷题。就简单提一些需要注意的点吧。

Python也提供了三种循环格式:while循环、for循环和循环;循环中有两个保留字:

continue:立即结束本次循环,跳入下一个循环。

break:跳出break所在的这层循环,考虑到嵌套循环的话。

python中又多出一个else,循环正常结束执行else中的代码,如果是break或return退出的话则不会执行。

关于range函数:三个参数与切片中的三个参数含义十分相似。分别为开始数字、结束数字的后一位、步长。其中开始数字默认为0,步长默认为1。

传一个参数:表示结束数字的后一位,开始数字、步长取默认值。

for i in range(5):
print(i)
>>> 0
>>> 1
>>> 2
>>> 3
>>> 4

传两个参数:第一个表示开始数字,第二个表示结束数字的后一位,步长取默认值。

for i in range(1,5):
print(i)
>>> 1
>>> 2
>>> 3
>>> 4

传三个参数:按次序分别表示开始数字、结束数字的后一位、步长。和切片一样,有了步长,我们就可以进行倒序循环了:

l = [1, 2, 3, 4, 5]
for i in range(len(l) - 1, -1, -1):
    print(l[i], end=" ")
>>> 5 4 3 2 1

这里先定义了一个列表l,循环里i从l的长度减一位(即最大索引)开始,每次递减1,直到0,打印当前循环下l的元素,共循环5次。

关于循环:在java中被称为加强for循环,深受后端开发者喜爱。这个循环可以让我们遍历一个字符串、列表、元组、字典、集合,以及其他支持迭代的数据类型。

考题里出现最多的是对字符串和列表的for in循环,分别举例:

s = 'python'
for ch in s:
print(ch,end=' ')
>>> p y t h o n

每次循环中的ch代表了字符串里的一个字符,循环次数等于字符串长度。

songList = ['稻香','牵丝戏','打上花火',
'Love Story','Flower Dance','Walk Thru Fire']
for song in songList:
    print(song)
>>> 稻香
>>> 牵丝戏
>>> 打上花火
>>> Love Story
>>> Flower Dance
>>> Walk Thru Fire

一般这种列表名称就命名为存储的变量名再加上List或者命名成songs,循环的话元素名就用song这样。

13.异常处理浅析

知识点很碎,而且书上好像没专门提。且不说非编程专业,信工院的同学也很少使用异常处理,见得少理解起来就更麻烦了。

有这三种语法try-except、try-except-else、try-except-finally。

其中,try模块和except模块是必须的,try中可能出现异常代码,except块负责处理异常,而else块和finally块负责做一些善后工作,可有可无,可一起出现也可分开出现,都没问题。

和分支结构采用一样的思路,先看题再延伸吧:

A选项相信只要是跑过python程序的人都懂,像语法错误啊、索引超出范围啊、文件读取不到啊,一旦出现直接寄,管后面写得再好都没用。

B选项的话是这样的,要是一个程序可能出异常的代码占了一半,也不大正常。

C选项解释了else块的作用:仅在try块中代码不出现异常时执行。

D选项就离谱了,except块才是用来处理异常的。

我们拿文件处理举例吧:几千行的代码中把对一个文件处理的十几行代码放在try块中,如果文件没有找到,报FileNotFoundError异常,会直接进入except块中处理异常。即使处理完异常,文件该找不到还是找不到,那么和文件处理有关的代码就不用执行了,因此也就没必要再回到try块中,继续往下走。往下碰到else块,由于报了异常,不搭理它。再往下碰到finally块,人都叫这个名字了那就执行呗。

try:
    file = open('期末过不了.txt')
    print('期末过不了')
    file.close()
except:
    print('就是找不到!')
else:
    print('读取成功!')
finally:
print('文件处理结束! ')
>>> 就是找不到!
>>> 文件处理结束!

try块中,先读取一个名为“期末过不了”的文本文件,由于读取不到,跳过下一行的打印直接进入处理FileNotFoundError的except块并执行代码。触发异常后不执行else块,最后还需执行finally块中的代码。else做验证,finally做总结。

注意:一个try-except块中可以有多个except块加上异常名来处理不同异常:

a = 10
b = 1
try:
    c = b / (b // a)
    print(c)
except IOError:
    print('我不大可能输出,写着玩!')
except ZeroDivisionError:
print('我看你的小脑袋瓜一定是热昏头了!')
>>> 我看你的小脑袋瓜一定是热昏头了!

try块中,我们先用1整除10得到0,这样就会报除以0的异常了。

异常与错误的区别:确实都会引起程序终止,但这两个并不是同一个东西。区别在于,引起程序终止的时间点不同。

错误一般指语法错误(SyntaxError)。指初学时容易犯的诸如冒号没加、缩进问题、括号不对称等错误。现在的编辑器已经能做到运行前检查语法,确保能正常运行。而异常呢就是程序运行时发生的问题。

拿自然语言举个例子,比如说你正在和一个看不懂中文的英国人聊天,聊天软件有翻译功能。你说一句“你真好看!”,翻译软件先检查语法,主谓语顺序是对的,没问题,翻译成“You are very beautiful!”发给对方。对方读句子,想这句话的含义,按他们的思维理解了。交谈很顺畅!但是,如果发成了:“你好看真!”翻译软件首先会看出语法有问题,直接告诉你这句话语法有问题,并不会发给对方。

至于异常,比方说你问对方:“5除以0等于多少?”软件检查没有语法问题,翻译并发送过去。对方也能读懂并思考含义,但他可能会回一句:“wtf”。

Python中也是这样,第0节我们提到,python是解释型语言,是逐行解释运行的。(事实上,为了减少解释型语言与编译型语言运行速度上的差距,python也引入了编译代替解释,这个过程并不是强制的,且后续操作上与编译型语言不同)在解释一句代码时,首先会进行词法检查和语法检查,用了未定义的变量、冒号漏加或括号没对称都会导致出错,程序直接返回。此时报的错是错误,不是异常。当顺利通过词法与语法检查,程序得以运行起来后,这时再出现的问题才是异常。

14.列表、元组、字典、集合浅析

这一块,知识点相当琐碎,而且是python的核心内容。这一节先简单介绍各类型之间的联系,再结合题目分开讲。

首先先了解几个概念:组合类型、序列类型(字符串、列表、元组)、集合类型(集合)、映射类型(字典)。他们之间的关系如下图:

组合数据类型和之前讲到的数字类型有很大不同,它不是一个具象的类型,只是一个承载数据的容器,不同的组合类型功能各有偏重。包括字符串,也可以看做是承载字符的元组。

序列类型的最重要特点就是有序,有序意味着可以被索引,被切片。Python对此作了优化,实现了双向索引,简化了逆序输出。其中,列表是可变的,而字符串和元组一经定义内容就不可变。

集合类型只有一个实现类:集合。性质也很简单:无序、确定、互异。支持集合间交、并、差运算。

映射类型也只有字典一个实现类,由键值对构成,运用是上述中最广泛的。

作为组合数据类型,自然可以相互嵌套,但还是得按照性质来。比如列表、字典中的元素是可变的,而集合要求元素或元素中的元素都是确定不可变的,因而这两个就不能作为它的元素。集合中可增删元素,因此集合不能嵌套集合。字典的键的性质与集合相同,因而不能使用列表、字典和集合,一般都是用字符串作为键,字典的值没有约束。字符串不能嵌套其它类型。

# 字符串只能承载字符
s = 'python'
# 列表什么都能塞
ls = ['s',[1,2,3],(1,2,3),{'a':1,'b':2},{'a','b','c'}]
# 元组同列表
tup = ('s',[1,2,3],(1,2,3),{'a':1,'b':2},{'a','b','c'})
# 集合不能放列表、集合和字典
set = {'s',(1,2,3),}
# 字典的键不能是列表、集合和字典,值没有要求
dict = {'s':'t',(1,2,3):[1,2,3],1:{1,2,3}}

元组不能往里添加元素,但其内部元素却可以通过函数修改,是可变的,因而使用场景较少。

集合可以增删元素,实现集合的运算,虽然自身没有查询方法,但可以强制转换成列表,因而可用于数据的保存与合并。

    列表和字典的使用是最广泛的,以这两种类型衍生出来的组合类型不胜枚举,功能也强大到发指。

先来看看列表:

      列表的索引范围是[ 0, len(list) );append(x):把x元素添加到列表末尾

这题是比较简单的,向往里添加一个整型值2050,再添加一个列表,列表里有两个元素。因此选C。

这里爆红是因为在定义ls列表时只往里添加了字符串类型,编辑器认为这个是只存字符串的列表。而列表是可以添加任何类型的元素的,因此不影响运行。

pop( [ i ] ):删除列表中索引为i的元素,不加索引参数则默认删除最后一个,并返回这个元素。

remove( x ):删除列表中第一个值为x的元素,如果没有,则返回一个ValueError异常:

ValueError : list.remove(x): x not in list

这题我们先只看第一个空。列表中最后一个元素是“gains”,因此调用pop( )方法会把这个元素删除并返回。

words = ["no","pains","no","gains"]
print(())
>>> “gains”

 通过列表的append( )和pop( )方法,我们就可以实现一个先进后出的栈结构。

这题不仅仅考了remove函数,还有对列表循环的底层原理。遇到这种循环题,必须打草稿模拟程序的循环。

先整体看看:程序定义了一个字符串列表letter,开始循环列表元素:如果元素值等于字符串“D”,就把这个列表中的第一个D字符串删掉,循环结束后打印剩余列表。想到这里,是不是就会想当然地选A了呢?我们再循环一遍试试:

第一次循环,i为”A”,跳过if;第二次i为“B”,跳过;第三次i为“C”,跳过;第四次i为“D”,谨慎一点,进入if了:删掉letter列表中的第一个“D”字符串,现在列表还剩五个元素,为[“A”,“B”,“C”,“D”,“D”]。现在进入第五次循环,i等于第五个元素“D”,同样进入if分支删掉一个“D”。还会有第六次循环吗?显然是不会了,退出循环。最终,

letter列表剩下四个元素[“A”,“B”,“C”,“D”]。

草稿表意就好,语法都是自己现编的~

运行后也确实如此。

以下为拓展内容:

从底层上来看,对列表的循环是这样的:i先等于列表的起始元素,第一次循环结束后,调用列表函数取得列表的第二个值,以此类推。当在循环列表时使用remove方法删除一个值后,这个位置就空了,后面的元素要顶上来。那么,顶上来的这个元素可能正好就是下一次循环要被访问的。但是列表循环不管这个元素是否被访问过,只看访问到第几个位置,会因此错过一个元素。在实际开发中,这个逻辑错误是常有的事。

我上面的表述并不完全正确,但是这么个逻辑。毕竟主要还是面向非编程专业,没必要介绍内存、地址这些概念。如果有兴趣的话可以参考以下两个网址:

Python 列表在内存中的顺序存储_吟一句君埋泉下泥销骨的博客-CSDN博客

for 循环的底层逻辑 - 知乎

insert( i, x ):在索引为i的元素之前插入x元素。

用人话来说,x找到第(i+1)个元素,对它说:“哥们,有急事,插个队。”与remove函数一样,用在循环里需要注意位置问题。但一般insert考的较少,不好出题。

 这个就是上面那题改的代码,简单的循环跑十秒没跑完,妥是死循环了。至于为什么,留给大家想吧。

index( x [ , __start, __stop ]):返回列表中值为x的元素的第一个索引,__start和__stop为可选参数,表示查找的开始索引和结束索引的下一位,默认的范围为整个列表。如果没有找到会返回一个ValueError异常:

ValueError : x is not in list

count( x ):返回列表中值为x的元素出现的次数。

count函数考的不多,index函数倒是能和别的知识点联动一下。

先看个简单的吧,列表中有120、“120”、字符串转成整型的120和12*10得到的120,index函数返回第一次出现120的索引,为0;count计算120的数量,为3。

难一点的题也可以这样出:先调用全局函数min求得列表中最小的元素,返回它的值。又把这个值作为index函数的参数取得这个元素的索引。再把列表第一个元素与最小元素的位置对调。答案是A。

copy( ):返回一个与原列表元素相同的新列表。

clear( ):将列表元素清空。

sort( )reverse( ):对列表排序,分别是正序和倒序。

这四个单看起来都很简单,但是题目就可以把它考得很复杂。一方面是复杂在返回值上,copy函数有,下面三个没有;一方面是对组合类型的赋值上:     简单来说,对于数值类型,即使把一个变量的值赋给新变量,python也会为新变量开辟一块新空间存储(这句并不准确,实际情况会放在下面的拓展中讲),而组合类型不然。试想一下,一个存了上千、上万个数据的列表,如果赋给新变量就再开辟新空间给它,那我用一个简单的循环就可以把16g内存撑爆了。因此,赋给新变量的列表仍是那个列表,只是换了个名字而已,当然也定义了copy函数来实现为新变量对应的列表开辟新空间存储。从这里就可以看出,普通类型和组合类型在赋值上的区别了,这也是二级喜欢考的点之一。

以下为拓展: id函数取得一个变量在内存中的初始十进制地址。

我们定义了两个整型变量,可以看见,它们也是共用一个空间存储的。这是一种节省内存的机制,甚至把c = f替换为c = 1,它们仍共用一块内存。因为python是为整数1分配一个内存空间,变量c和f都指向这个1。(事实上,也只有在 -25 ~ 256范围中的整数才不会重新分配内存空间。如果让c = 257 tab f = 257,c和f的地址就不一样了)因此,当将c重新赋值为2后,c的内存始址就变了:

 再看看组合类型会不会变呢:

即使我们修改了c的元素,它们仍共用一处内存。

打印后发现,两个变量值都被修改了(format是真好用)。不仅是append函数,如果调用clear、sort、reverse函数,都会同时修改两个变量,这里就不举例了。

如果调用了copy方法,则对c列表的操作并不会影响到f。

注意,列表中的copy函数仅对列表进行了浅复制,并不是深复制。个人认为python考不到这么深,故不展开。有兴趣的可以了解:通俗易懂,搞定Python中的深浅拷贝 - 知乎

在这题中,把lt的列表赋给ls,但它俩仍对应同一个列表,对任意一个变量的操作都是对同一个列表的操作,因此最后输出空列表。

这题就有点不同了,L2是从L1调用copy方法返回的新列表,只是元素与L1中相同。因此,对L2的操作都是在新列表上进行的,不会影响到L1,故L1还是[ 1,2,3,4 ]

两个有趣的小点:

 全局函数sorted( )reversed( )与列表函数sort( )reverse( )的区别:sorted( )和reversed( )对列表排序是有返回值的,返回一个排好序的新列表,而sort( )、reverse( )仅能对当前列表元素进行排序,没有返回值如果输出诸如( )和ls.reverse( )都是None!

现在,我们再来看这题的第二空,sorted方法对words列表排序,reverse参数表示按倒序排,最后取返回新列表的第一个元素输出,所以是pains。 

Python提供了一种渐变定义列表的方式:

ls = [x for x in range(10)]

 表示把每次循环最后得到的x添加到列表中。由于这里对x的操作不会太复杂,因此题目一般不难。

像这题,仅对每次循环的x进行了平方操作。ls为[ 0,1,4,9,16 ]。

至于元组,考的少提少一点。主要运用场景还是在函数的定义和调用上。函数名后面的参数列表,其实就是一个元组。调用函数时,也是以函数名加一个元组的方式使用。

下面来看字典:

字典是无序的,字典的长度等于字典中键的个数。字典存放键值对( key: value ),键名相当于索引,值相当于元素,字典的索引和值都具有意义。

字典函数:

get( key[, __default ):返回指定键key的值,如果键不在字典中,返回可选参数__default的值,默认为None。有一种简便的替代写法:

dict['key']

但这种写法必须确保字典中有’key’键,否则会报KeyError异常:

KeyError: 'key'

setdefault( key, __default ):如果键存在,键值对不做改变,返回键对应的值;如果键不存在,则添加该键值对key: __default。同样有一种简便的替代写法:

dict['key'] = 'value'

但是,如果字典中已存在键‘key’,新赋值’ value ’将替换原值。

这题中字典d嵌套了字典,通过’food’取得。但请注意,字典d中只有一个键值对。因此,对d使用get方法是获取不到键为‘egg’的键值对的。因此输出默认值‘no this food’,如果对’food’使用get方法则可以正常获取到。

下面爆红是因为前面d的get方法有可能返回None类型,而None类型中并没有get方法。但我们提前清楚字典d中的‘food’键值对的值是一个字典,因此可以不管编辑器的报错运行出来。

setdefault函数我并没有找到例题,就拿上面的题改编下吧: 

d = {'food':{'cake':1,'egg':5}}
d['fruit'] = {'banana':1,'pear':5}
d.setdefault('fruit',None)
print(d['fruit'])

这里先在字典中新建了一个键值对,再使用setdefault函数对‘fruit’键值对赋值,最后输出这个键值对。输出应该是:

{'banana': 1, 'pear': 5}

因为当字典中已有该键值对时,setdefault不会对其进行修改。

copy( )clear( ):与列表中基本一致,不再多说。

keys( )values( )items( ):分别返回键、值、键值对数组迭代器用于循环,返回的类型分别为dict_keysdict_valuesdict_items不是列表!但都可通过list( )方法转换成列表。

d = {'1': 2, '3': 4}
print(d.keys())
print(d.values())
print(d.items())
>>> dict_keys(['1', '3'])
>>> dict_values([2, 4])
>>> dict_items([('1', 2), ('3', 4)])

有了上面的经验,我们来看这题:先定义了一个tb字典,将tb中的键值对取出循环,看着是要把给stb赋值,最后输出stb,问应该怎么赋值。可以看出,stb相当于把tb的一个键值对的键和值对调。再看循环,每一次循环的it是一个键值对元组,第一个元素是键,用it[ 0 ]取得,第二个元素表示值。这样,值就有两种GPT CSDN,一个是直接用it[ 1 ]取得,还可以通过tb[it[ 0 ]]取得,而键只有一种。

这下就好办了:stb的键都是tb的值,就有了stb[ it[ 1 ]],等于tb的键,就有了it[ 0 ],把后者赋值给前者即可。这一题选A。

运行一遍正常输出。

pop( key[, __default] ):删除字典给定键 key 所对应的值并返回。如果不指定__default且字典中没有键key,报KeyError异常:

KeyError: key

 也有一种替代写法,通过保留字del删除键值对:

del dict['key']

同样,如果没有找到这个键会报KeyError异常。

popitem( ):删除字典中的最后添加的键值对。

考题和上述的set方法类似,不再提了。

还有一个小点:在逻辑判断中,可以使用保留字in判断键是否在字典中:

if 'key' in dict:
    print('yes')

输出是"yes"

集合:

主要就是考它的性质和几种集合运算吧,集合函数也和之前的差不多。仅列举一下集合运算的写法:

set1 = {1, 2, 3, 4, 5}
set2 = {1, 3, 5, 7, 9}
# 交运算
print(set1 & set2)
print(set1.intersection(set2))
# 并运算
print(set1 | set2)
print(set1.union(set2))
# 差运算
print(set1 - set2)
print(set1.difference(set2))
>>> {1, 3, 5}
>>> {1, 3, 5}
>>> {1, 2, 3, 4, 5, 7, 9}
>>> {1, 2, 3, 4, 5, 7, 9}
>>> {2, 4}
>>> {2, 4}

可以看出,python中对集合运算既有函数实现,也可用替代符号。

15.函数性质、参数机制浅析

函数,英文名叫function,在C语言书中翻译成函数,在java书中又翻译成方法。叫啥不重要,是同一个东西。函数承载了一系列的代码,用以实现某种功能。一般在开发中,如果一处代码(文件读取)有复用情况,则可以把代码抽离成一个函数,加上文件路径参数。以降低复杂度、提高可读性、实现模块化。

通过上面的解释,这里应该是可以用排除的方式选到B项的。其实函数并不能提高运行速度,相反,函数的定义会降低运行速度。在程序解释过程,如果遇到函数调用,python会跳转到定义函数的地方执行函数,执行完成后再回到主程序中,这个过程会有时间开销,不过基本可以忽略不计。

返回值:

函数可以有返回值也可以没有返回值,没有返回值返回None;一个函数中可以有多条return语句返回多种不同类型的值;一条return语句可以返回一个值也可以返回多个值。返回多个值时,以元组的形式返回。

我们主要看看函数参数的机制:

    参数可以分成必需参数、可变必需参数和可选参数。(名字瞎起的,重在表意,看完哪种参数在书上叫啥应该都明白)

必需参数和可变必需参数是调用函数时必须要传的,而可选参数比较特殊,它是必需参数或可变必需参数的一种,但自带一个默认值,因此在调用时可以不用传入值。

必需参数是最常用的,比如列表的index、remove方法都要求传入一个参数作为查找的依据。也可以定义多个参数,传的时候依次传入即可。

 如果一个函数有返回值,在代码的末尾调用函数时python也能直接输出返回值。

有的时候开发者不能确定这个函数在调用时需要多少个类似的参数,因而又出现了必需可变参数,这个参数用字符串中的format函数来讲在合适不过了。

format函数定义了一套传值进字符串的格式,开发时肯定是不知道调用函数时传入多少个值的,可能一两个,也可能有数十个,因而使用了可变元组参数。我不管你传进来多少个值,我统一构造成一个元组,每个索引对应你的一个值,这总行了吧:

这里我传入了四个值,函数内部按元组存储,按索引输出的。

至于这个参数如何表示,在python中是参数前加一个“*”号的方式。

可以看出,这个args参数就是一个元组。我们可以按元组取值的方式去取其中的值,不再演示了。

注意,如果传入一个元组变量,则变量名前也需要带上一个“*”号,表示这就是args的整个参数列表了,否则将把传入的该元组作为args元组的一个元素。

然而,在实际开发中,我们更多是使用字典来存储数据,得益于键值对的操作简便(对象的存储使用键值对使得json使用键值对使得前后端数据交互使用字典,(扯远了))。需求决定内容,再引入一个可变字典参数是有必要的。

print('{language} {version[0]}
    .{version[1]}.{version[2]}'
    .format(language='python',version=[3,6,8]))
>>> python 3.6.8

 这里使用一个字典分别传入语言名和对应的版本号,语义较可变元组参数强得多。

如果要在python中表示可变字典参数,在变量名前加“**”即可。和元组不同,如果调用函数时传入的参数前没加两个“*”,就会报错。

了解了这个用法,上面的代码可以改成:

dict = {'language': 'python', 'version': [3, 6, 8]}
print('{language} {version[0]}
    .{version[1]}.{version[2]}'.format(**dict))

 这里差不多已经接近实际开发了,与元组相比优势更明显。

可选参数就很简单了,定义函数时在参数后加上“=”,再加上具体的值。为参数设置默认值也便于用户使用,诸如字符串的strip(默认以空格分隔)、center(默认以空格填充),列表的pop(默认删掉最后一个元素),字典的的get(找不到键默认返回None)都是可选参数的运用。

传入参数时也要考虑顺序问题:可选参数优先级最低。两种必需参数中,可变必需参数排在必需参数之后。假设函数里有一个必需参数和可变必需参数,如果先传了可变必需参数,那后面第几个才是前面的必需参数呢?具体题目里,怎么顺怎么来。

此外,可以通过指定参数名的方式不按顺序传入必需参数,很少使用但题目会考,实际一般都直接按顺序传值。

def func(x, y):
    pass
func(y=5, x=2)

16.变量的作用域问题:

先讨论一下函数的参数:

参数分为形式参数实际参数。形式参数为函数定义时写在参数列表里的变量,实际参数为调用函数时往参数列表里添加的变量。 对于数字类型,由于所占空间不大,因此当一个实参传入函数时,程序为这个实参的值又重新开辟了一个空间,让函数里的形参指向这一块。也就是说,对形参的处理不会影响到函数以外。

这里定义了一个swap函数,用以对调x和y的值,但调用swap后,函数外的x、y值并没有对调。

对于组合类型就不存在上面的问题了,它问题更大。如果每调用一次函数,就要为一个可能承载数万条数据的列表、字典开辟一块新的空间给形参,那内存很快就被刷爆了。因此,传入形参的话传进去是啥就是啥,对它的处理会影响到函数以外的。但是,一旦函数结束,形参也就随之被清理掉了。如果形参作为返回值传回主程序,在内存中保留了这个值,但形参变量将被清理。

在函数中对lt添加值4,函数外的ls也被添加了4。函数内的lt与函数外的ls是同一个列表。字典、集合也都如此(字符串和元组一经定义不可改变)。

再来看变量:

变量分为全局变量和局部变量。全局变量前面一般没有缩进,局部变量一般定义在各种体中,如函数体、循环体等。

如果在某个体中定义的局部变量与全局变量重名,以局部变量为准。

if条件块中的a与全局变量a重名,但输出if块里a的值。

如果想在一个体中使用全局变量也可以,通过global关键字调用即可,一般只在函数体中使用。主程序中注意控制变量命名随时都可调用全局变量。注意,调用了全局变量后,对它的修改同步到函数以外。当在函数中调用全局的组合类型变量时,无需使用global关键字。

先调用func函数,在函数中调用全局变量a,修改后输出,再在主程序中输出,两次都是修改后的值。

这题要注意的点就是传参时把实参b传给了形参a,实参a传给了形参b。因此,调用函数后c的值是24。函数中把a的值赋给b与主程序中的b无关,因此b的值还是2。

这题考察了在函数中使用全局变量。在函数中,sp加上了12并返回,但这是发生在输出第一个sp之后的事了,因此结果是100 112。

17.python内置函数

像print、input、eval就没有什么要介绍的必要了。这类函数只要了解功能,就能选出答案,题目不会太难。

int( )str( )list( )dict( ):这一类函数还有tuple( )、set( )等,不管官方名叫啥,我更喜欢称为强制类型转换函数。简单看下用法以及输出:

print(list(range(5)))
print(str([1,2,3,4,5]))
print(int('100'))
>>> [0, 1, 2, 3, 4]
>>> [1, 2, 3, 4, 5]
>>> 100

 第一个是把range函数里不知道是什么类型的0、1、2、3、4变成确定的列表类型;第二个是把列表转换成字符串类型;第三个是把字符串转换成一个整型值。

chr( )ord( ):chr函数传入一个整型值,返回该整型值对应的Unicode字符。ord函数传入一个字符,返回该字符对应的Unicode编码。Unicode字符集是对ASCII字符集的补充。这两个函数在之前说ASCII码的拓展中有提及,读到这里的同学再回头看6. 字符串比较一定感觉小菜一碟了。

all( )any( ):传入可迭代参数(理解为组合类型就够了),对其中每个元素进行判断。all:有假为假,同and;any:有真为真,同or。

print(all([1,2,3,[]]))
print(any(('p','y','t','h','o','n')))
>>> False
>>> True

divmod( ):传入两个数(不可带虚数),返回商和余数的元组。

divmod(5.5, 2)
>>> (2.0, 1.5)

zip( ):将多个可迭代参数同时开始迭代,每一次迭代创建一个元组,当次迭代位置对应的元素依次填入元组中,最后返回元组组成的列表。

t = list(zip((1,2,3,4,5),[6,7,8,9,10,11],'sasasa'))
print(t)
>>> [(1, 6, 's'), (2, 7, 'a'), (3, 8, 's'), 
(4, 9, 'a'), (5, 10, 's')]

可以看到,有的多余元素没有放进最终元组中。

这题看着很长,但思路很简单。每次zip函数打包的都是整个x和y,与循环无关。因此字典z中每个键的值是一样的,且值的最外层用中括号包裹表示列表。故选A。

写在最后:

由于自己也要复习,文件和第三方库那块就不搞了。文件处理用得少,考的题也不多。第三方库那边,,说实话我也不懂,只是停留在会用的层面,难以讲清。


原文地址:https://blog.csdn.net/2401_82891588/article/details/136430631

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值