本文是在阅读裘宗燕老师的《程序员学python》后对python中与C、java等语言不同的地方的总结。
第一章 python基础
1.算数运算符://整除 /除 **乘幂
2.复数的虚部加后缀j或J,如(1+2j)
3.python能处理任意大的整数
4.底数前的正负号在乘幂之后作用,其他情况下正负号先作用,如下
5.一行的最后字符是反斜线\,这时解释器把下一行作为本行的继续,这种反斜线称为续行符。
6.函数abs求绝对值;max、min求实参中的最大值和最小值,允许有多个实参;round求浮点数的近似值,可以增加一个整数说明保留的小数位数。如下:
7.导入语句有import有几种形式:
(1)from math import *:导入math包的所有功能,使它们都能直接使用。
(2)from math import sin, cos:导入math包,并使其中两个函数sin和cos直接可用,列出多个名字时用逗号分隔。
(3)import math:导入整个数学包,但其中的功能只能通过math.sin、math.cos的形式使用。这样做只在环境中加入math的定义,有利于避免名字冲突。
8.python中字符串的类型名为str
9.字符串字面量:
(1)用一对单引号或者一对双引号括起的一串字符。
(2)一对连续的三个单引号或者一对连续的三个双引号作为括号。在这种字面量中可以换行,换行符也作为字符串的内容。
10.标准函数len用来求字符串长度。
11.字符串中每个字符有一个位置,称为下标,下标的值一般从0到len(s)-1,但python允许负下标,-1表示最后一个字符,以此类推。
12.加法运算符也表示字符串拼接操作。
13.切片操作:
(1)s[m:n]:得到包含字符s[m]到s[n-1]的串
(2)s[m:n:d]得到下标m到n-1范围里,按下标步进值d选出的字符构造出的串。m省略时表示0,n省略时表示len(s),d省略时表示1
14.给原来没定义的变量赋值,该变量就有了定义(赋值即定义规则)
15.输出函数print,多项输出之间加空格分隔,如下
16.注释:用#开头
17.赋值语句的两种扩展形式:
(1)变量=变量=.....=表达式
(2)变量,变量,......=表达式,表达式,.......
第二种形式要求把一系列表达式的值分别赋给一系列变量,按位置对应,变量和表达式的个数必须相同。
18.pass语句,执行时什么也不做,常用于填补结构缺位.
19.python种不返回值的标准函数都返回特殊值None,如果不需要结果,或没有合适的值作为结果,就可以考虑用None.
20.python允许在一行中出现多个语句,这时需要在语句之间加分号.
x = len; y = x + 1
21.逻辑类型bool,逻辑值用关键字True和False表示.
22.逻辑运算符:or或(或者) and与 not非(否定)
23.x>1andx<10可以简写为1<x<10;x>10andx>y**2也可简写为10<x>y**2.
24.if语句的扩展形式:
if 表达式:
语句组
elif 表达式:
语句组
else:
语句组
解释器至多执行其中的一个语句块.
25.数值类型的0值都当作假,这些类型的所有非0值都当作真.另外,None也被当作假.组合类型的各种空值也当作假,包括空表,空元祖,空字典,空集合.
26.for语句用一个迭代描述来控制成分语句组的重复执行,基本形式是:
for 变量 in 迭代描述:
语句组
27.两种简单的迭代描述:
(1)用逗号分隔列出若干表达式,表示一个值序列
n = 3
for i in n+2, n-1, n**2:
print(i)
(2)标准函数range描述整数的等差序列,常用于for语言
s = 0
for i in range(100):
s = s + i
28.range的几种调用形式:
(1)range(n)表示序列0,1,2,......,n-1
(2)range(m,n)表示序列m,m+1,......,n-1
(3)range(m,n,d)表示序列m,m+d,m+2d,........,是等差值为d的序列(d为负时序列递减),直至最接近但不包括n的那个值.
调用range得到的对象称为迭代器(对象).
29.循环描述只在for语句开始时求值一次.
30.while语句
while 表达式:
语句组
31.循环控制:
(1)break语句:结束当前循环语句.
(2)continue:结束本次迭代.
32.函数定义:
def 函数名(参数列表):
语句组
33.变量是程序中最基本的抽象机制,是一种值抽象.
34.标准函数isinstance(x,t)专用于检查x的类型是否为t,如下
#检查a的是否为int类型的
isinstance(a, int)
35.断言语句的两种形式:
(1)assert 条件
断言语句强制要求断言成立,否则就报错.如果执行时条件为真,这个语句就结束;否则就报告AssertionError,默认情况下导致程序终止.
(2)assert 条件, 表达式
这种形式里的表达式可以是任意表达式,条件为假时求该表达式,得到的值作为AssertionError的参数.
与if语句不同,断言语句应该只用于程序正确执行的必要条件.
例:以求阶乘函数为例.显然,这个函数必须是整数,参数为负时阶乘无定义.加入断言语句后的函数定义是:
def fact(n):
#断言,如果n不是整数或者不是正数则程序报错
assert isinstance(n, int) and n >= 0
prod = 1
for k in range(2, n+1):
prod = prod * k
return prod
36.文档串:python提供文档串机制,如果函数体里第一个语句是字符串,它就是该函数的文档串.
37.python允许在函数中定义局部函数
38.随机数:
(1)random():返回半闭半开区间[0.0, 1.0)中一个随机浮点数.
(2)randrange(n), randrangr(n, m), randrange(m, n, d):返回给定区间里的随机整数
(3)randint(m, n):相当于randrange(m, n+1)
(4)choice(s):从字符串s里随机选取一个字符.
(5)seed(n):用整数n重置随机数生成器,其无参形式用系统当时的事件重置随机数生成器.调用seed()就是要求重新开始一个随机序列.
39.lambda表达式
(1)python提供了用于描述匿名函数的lambda表达式,lambda表达式是一种表达式,用于描述小的匿名函数.
(2)语法形式
lambda 参数,...: 表达式
(3)lambda表达式求值得到一个匿名的函数对象,它以描述中的参数为形参.调用这种函数对象时先建立形实参关联,而后算出表达式的值作为结果.
(4)lambda表达式可以直接当作函数使用,也可以赋给变量或传给需要函数参数的函数等.下面的lambda表达式被作为函数直接应用于实参:
(lambda x, y: x**2 + y**2)(3, 4)
这是一个函数调用式,其值是25.注意,由于优先级问题,这里的lambda表达式必须加括号.
(5)实例:
#普通单行函数
def sum(x, y):
return x+y
#lambda表达式
p = lambda x, y:x+y
print(p(4, 6))
要点:lambda函数不能包含命令,并且包含的表达式不能超过一个.
(6)lambda匿名函数的格式:冒号前是参数,可以有多个,用逗号隔开,冒号右边的为表达式.其实lambda返回值是一个函数的地址,也就是函数对象.
40.作用域
(1)python解释器处理程序时首先扫描代码,根据赋值即定义规则静态确定局部作用域里定义的变量.在一些特殊情况下,这种规定可能带来出人意料的现象.
代码:
x = 1
def fun2():
y = x #这时无定义
x = 2
return x + y
错误信息说在带注释的语句处变量x未赋值就使用是错误的.首先,函数定义看作一个整体,解释器静态检查fun2函数体的代码,确定局部定义的变量,这里出现了对x和y的赋值,因此它们都是局部变量.根据唯一定义原则,fun2里出现的x和y都是这两个局部变量的使用.然而,在执行函数体的第一条语句时,局部变量x没有赋值,因此解释器发现了局部变量未赋值就使用的错误.
(2)在变量定义与作用域的关系方面的3条规则:
(1)在一个作用域里,一个名字只有一个定义;(唯一原则)
(2)如果出现作用域嵌套,内层作用域里的变量定义屏蔽外层作用域里的同名变量.如果没有屏蔽,局部作用域里可以使用外围作用域中定义的变量;(就近原则)
(3)互不嵌套的不同作用域里定义的同名变量相互无关.
41.全局和非局部声明
(1)全局变量声明语句,其形式是:
global 变量名, ......
这种语句应该出现在局部作用域里,关键字global后可以列出多个变量名,用逗号分隔.
(2)非局部变量
有时也需要在内部函数定义里修改外围函数的变量(而不是全局变量).python为这种需要引进了nonlocal声明语句,形式是:
nonlocal 变量名, .....
这种语句声明在本函数体里出现的变量名不是局部变量,应该到外围(但非全局)作用域去找它们的定义,找不到就是错误.
(3)一个lambda表达式也引入一个局部作用域.
42.带默认值形参和关键字实参
(1)如果要给带默认值形参提供值,应该用"形参名=表达式"的实参形式,这种实参形式称为关键字实参,形参名称为关键字.关键字实参必须出现在普通实参之后,多个关键字实参的顺序不重要,解释器用实参的关键字与函数形参匹配.
(2)带默认值形参应该排在所有无默认值的形参之后.
(3)无关键字实参顺序匹配(在没有关键字的情况下).
43.字符集
python采用统一码字符集unicode,源文件默认采用utf-8编码,但允许在源文件第一行给出特定的编码说明.最常见的编码说明形式是:
# -*- coding: <encoding-name> -*-
44.python语言的关键字
and as assert break class continue def del else except elif False finally for from global
if in import is lambda None nonlocal not or pass return raise True try while with yield
45.循环语句的else段
(1)在for语句和while语句的主体部分之后都可以有一个else段,该段以关键字else作为头部(后跟一个冒号),该段的体也是一个语句组.
(2)当for语句完成了对所有迭代值的循环迭代,或者while语句的条件求出假值时,解释器执行其else段语句组,执行完毕后这个循环语句结束.如果循环体由于其他情况结束,例如遇到break语句或return语句,就不执行else段.
(3)else段可用于描述只在循环语句正常结束时需要做的操作.
第二章 数据的构造和组织
2.1.1表(List)
1.表的类型名为list(又叫列表).
2.表的创建:
(1)列举式:
a1 = [1, "Math", 89.7]
b1 = [sin(1.0), cos(1.0), tan(1.0)]
方括号里的元素可以是任意表达式,空表用[]表示.
表是序列,可以用下标访问表中的元素,首元素的下标是0.
标准函数len可以求出表的长度.list1[-1]得到list1的最后一个元素.
表对于元素没有限制,表的元素也可以是表.
元组和表只有一点差别:表可以修改,元组创建之后就不能修改.
(2)通过操作构建新表:
表类型名list也是一个标准函数,可用于创建新表(实际上是做类型转换),list实参应该是序列或者迭代器对象.
list2 = list("abc")
相当于列举式["a", "b", "c"],把字符串看作字符的序列.
list3 = list(range(100))
python把迭代器和序列统称为可迭代对象(python术语iterable)
操作+和*可用于各种序列,应用于表时得到新表.如果list1和list2都是表,在list1+list2得到的表前面顺序排列着list1的元素,后面是list2的元素.list1*n(n为整数)得到list1的元素重复n次的表.
下面是两种经常用到的表:
(1)构造已知长度的全0值的表,用[0]*n;
(2)构造一定长度,元素值待定的表,用[None]*n.
list1.append(x)把x加入list1作为最后的元素.
3.处理表的基本方法
(1)最直接的写法是:
for i in range(len(list1)): #用表长度生成循环范围
......list[i].......
实际上,序列也可以作为迭代描述,可用于逐个处理表中元素:
for x in list:
.....x......
注意,这种写法只能用于取得表元素,不能修改表元素(不能做元素赋值).
2.1.3元组(tuple)
1.元组的类型名为tuple.
2.元组也属于序列类型,元组对象可以包含任意多个元素,元素下标从0开始,可以用过下标表达式访问元组的元素.一个元组里的元素可以同属于一个类型,也可以属于不同类型.元组的特殊之处是创建后不能修改,结构不能变(不能加入和删除元素),其中元素也不能变(不能给元素赋值).
3.元组的创建和操作
创建元组的最基本方法也是列举式:
tp1 = (1, 2, 3)
元组列举式可以不写括号
tp2 = 1, 2, 3
可以用标准函数tuple创建元组,实参应该是可迭代对象,可以是迭代器,或者表,字符串等.tuple()或()都可用于创建空元祖.
应特别注意,创建只有一个元素的元组时,逗号是必须的,括号则不重要.
不写逗号的带括号表达式,如(12),被认为是突通的加括号表达式,用于说明表达式的运算顺序和优先结合,而不是元组.
元组也可以任意嵌套.
虽然元组本身不能变化,但可以包含能够修改的元素
4.赋值中的打包和拆分
python支持一对称为打包和拆分(解包)的隐式动作,是我们可以方便地把若干数据项包装为一个整体,或者把包含几个元素的对象拆开使用.
实际上,各种序列都可以拆分,只要赋值两边的结构相同.
a, b, c = [1, 2, 3]
a, [b, c] = [1, (2, 3)]
a, (b, c), d = [1, (2, 3), 4]
允许两层拆分.
如果序列s1的元素都是包含两个元素的元组或两个元素的表,可以写:
for x, y in s1:
....x.....y....
在迭代中,变量x和y将分别以s1的一个元素的两个成员为值.