python基础之3
1,列表可以嵌套任何东西。包括字典,列表等
字典是无序的健值型,不需要下标,也可以嵌套列表和字典
2,集合:对列表进行差异化处理后形成集合,特点:去重和无序。
主要作用: (1)去重;(2) 关系测试, 交集\差集\并集\反向(对称)差集
list_1 = [1,4,5,6,4,52,56,3,4,]
list_1 = set(list_1) --------------- 去除列表中的重复的数据
print(list_1,type(list_1))
--->
{1,3,4,5,6,52,56} <class 'set'> # { }大括号就是集合的标志。像字典,但不是,集合里面的元素也是无序的。
list_2 =[2,6,0,22,8,54,52]
print(list_1,list_2)
交集:取出两个列表里相同的元素(注意:list_1是集合,而不是列表,列表是没有.intersection的方法的,list_2可以是列表,也可以集合)
print( list_1.intersection(list_2) ) ------> {6,52}
并集:将两个列表合并起来去掉重复的:
print( list_1.union(list_2) ) ------>{0,1,2,3,4,5,6,22,54,56}
对称差集:去除两个集合中相同的元素后组成的集合,= 并集 - 交集
print( list_1.symmetric_difference(list_2) ) #对称 差集
差集:我有的而你没有的
print( list_1.difference(list_2) ) ------- 1里面有的,而2里面没有的。
子集:判断1是否为2的子集,返回值为True 或者 False
print( list_1.issubset(list_3) ) 意思是:1里面的元素是否都在3里面。1是否为3的子集。
父集:
print( list_3.issubset(list_1) ) 这个判断就是上面子集判断的反判断,学会用上面就行了。
判断两个列表之间有没有交集,若没有就返回True,有就返回False
list_3 = [1,2,3,4,5]
list_4 = set([5,6,8])
print(list_3.isdisjoint(list_4)) -----------> False
list_4 = set([9,6,8])
print(list_3.isdisjoint(list_4)) -----------> True
3,对集合进行处理操作形成新的集合:
s = set([1,2,3,4,5,6,7,8,9]) 创建一个数值集合
t = set('hello') 建一个唯一字符的集合----------------> {h,e,l,o}
a = t | s # t 和 s 的并集 -----》 print(list_1 | list_2)
b = t & s # t 和 s 的交集 -----》 print(list_1 & list_2) 运行结果为空的集合:-------> set()
c = t - s #求差集(元素在t中,但不在s中) -----》 print(list_1 - list_2)
d = t ^ s #对称差集(项在t 或 s中,但不会同时出现在二者中) -----》 print(list_1 ^ list_2)
4,对集合进行增删改查:
增加: (列表中的增加用append,insert),集合中没哟插入的,只能添加:add,
t.add('x') # 在 t 中添加一项(不能增加多项,会报错)
t.update([10,23,565,546]) # 在 t 中添加多项 ------ 用得少。
删除:
t.remove('x') 不会出现两个x元素的,因为天生就是去重的。(一次只能删除一个元素)
len(s) # set的长度
x in s # 测试 x 是否为 s 的元素,字典里也可以这样用,列表里也可以这样用,集合,字符串都可以这样用
x not in s .........不是.........
s.issubset(t)
s <= t #测试 s 中的每一个元素是否都在t中
s.copy() #返回 set‘s’ 的一个浅复制
discard:只删除指定的值,否则不删除
print( list_1.remove('dddddd') ) --------> 报语法错误,因为删除的这个元素不在list_1中
print ( list_1.discard('ddddd') ) --------> None (有这个值就删除,没有就报Nnoe) 但是删了之后不会打印出来
基本操作:
t.add('x') # 添加一项
s.update([10,37,42]) # 在s中添加多项
使用remove()可以删除一项:
t.remove('H')
len(s)
set 的长度
x in s
测试 x 是否是 s 的成员
x not in s
测试 x 是否不是 s 的成员
s.issubset(t)
s <= t
测试是否 s 中的每一个元素都在 t 中
s.issuperset(t)
s >= t
测试是否 t 中的每一个元素都在 s 中
s.union(t)
s | t
返回一个新的 set 包含 s 和 t 中的每一个元素
s.intersection(t)
s & t
返回一个新的 set 包含 s 和 t 中的公共元素
s.difference(t)
s - t
返回一个新的 set 包含 s 中有但是 t 中没有的元素
s.symmetric_difference(t)
s ^ t
返回一个新的 set 包含 s 和 t 中不重复的元素
s.copy()
返回 set “s”的一个浅复制
5,文件操作:三步:打开---->操作----->关闭
模拟创建实验文件:在pycharm里当前的项目下的同一个工作目录内,右键--->新建文件,命名为aa.txt,并在右侧编辑框内输入内容后保存。
再在相同的目录下,新建一个python file,开始下面的实验:
python里打开文件:
open('aa.txt') ---------------------------- 打开文件到内存中去,不会打印到屏幕
python里打开文件,接着读里面的内容:
open('aa.txt').read() --------------只会读到内存中去,不会打印到屏幕
将里面的内容赋给一个变量,并打印出来:
data = open('aa.txt').read()
print(data)
注意:当aa.txt文件全是英文字母或符号时,可以正常显示,当aa.txt文件里有中文字符时,会报错,因为此时没有指定字符编码,windows上打开文件默认就是gbk格式的。python默认的编码是utf-8,所以程序上用的utf-8处理不了gbk的
所以一般打开文件时要指定字符编码(此时就 不管aa.txt文件中是否有中文都可以正常显示出来了):
data = open('aa.txt',encoding='utf-8').read()
print(data)
对文件队形进行操作。将文件打开后赋给一个变量。通过修改变量达到修改文件的目的
f = open('aa.txt',encoding='utf-8') ------------> 赋给 f 的就是一个内存对象: 文件句柄(包含文件名,字符集,大小,在硬盘上的起始位置),不是文件的内容
实例说明:
f = open('aa','r',encoding='utf-8')
print(f) ---------------------------------------------> <_io.TextIOWrapper name='aa' mode='r' encoding='utf-8'>
f = open('aa','r',encoding='utf-8').read()
print(f) ---------------------------------------------> dss ----------------------------------------------> 返回具体的文件内容。
士大夫撒地方第三方士大夫撒地方撒都是阿斯蒂芬
针对文件句柄的读:(不是每次都从头读到尾的)
读:
f = open('aa.txt',encoding='utf-8')
data = f.read() ---------------当读完时,指针从文件的第一行一直走到末尾。
data2 = f.read() ------------------------->此时读到的是空值。
print(data)
print('---------datae---%s'%data2) ------->此时的data2为空值。
将data2 改成下面这样就有值了
data2 = open('aa.txt',encoding='utf-8').read()
理解方法:每个文件打开后才能读,一打开其句柄的指针位于第一行,而读是针对这个指针而言的,从上次的位置开始向后扫。当一个文件别读过后再读即为空文件,因为指针已经到了末尾。
写:
f.write('aaaaaaaa+++++++++++bbbbbbbbbb---------') # 此时理论上就会在文件末尾接着写,因为指针因为读,而从文件的开头跑到末尾来了。
# 此时会报错,提示文件不可写,python里需指定文件要么可读,要么可写
打开文件的模式:r 只读模式,默认也是这种模式
f = open('aa.txt',‘r’,encoding='utf-8')
写模式:w
f = open('aa.txt',encoding='utf-8')
data = f.read() ---------------# 此时会报错,此时不能读
f.write('aaaaaaaa+++++++++++bbbbbbbbbb---------') # 此时的写 是创建一个文件,会覆盖之前的文件
创建新文件
f = open('bb.txt','w',encoding='utf-8')
f.write('++++++++++++++++++++++')
f.write('======================')
f.close() -----------------> 程序结束时关闭文件
------>会在当前路径创建一个 bb.txt 的文件:‘++++++++++++,============= ’ 内容都在一行,并且用‘,’号隔开
f.write('++++++++++++++++++++++\n')
f.write('======================')
------>会在当前路径创建一个 bb.txt 的文件: ++++++++++++,
============
追加模式:a
f = open('bb.txt','a','encoding=utf-8') ----------------》注意此时的a模式下只能写,而不能读,后面接读的操作会报错,若为不存在的新文件则创建
f.write('++++++++++++++++++++++\n')
f.write('======================')
f.write('aaaaaaaaaaa\n')
f.write('vvvvvvvvvvv')
f.close
会沿着之前的文件内容接着写,不会冲掉之前的内容,此时仍然不能读,一读就报错。
注意:a模式也可以创建新文件
f = open('cc','a',encoding = 'utf-8')
f.write('\n+++++++++++++++++')
f.write('\n-----------------')
f.write('\n55555555555555555')
f.close()
f= open('bb','r',encoding = 'utf-8').read()
print(f)
一次读文件的前5行:
f = open("aa.txt",'r',encoding="utf-8")
print(f.readline()) -------------------------> 读文件aa.txt的第一行
print(f.readline()) ...........................................二...
print(f.readline()) ...........................................三...
print(f.readline()) ...........................................四...
print(f.readline()) ...........................................五...
readline参数就是一次读一行。
实例:a.txt的内容
a
b
c
d
e
f
g
h
f = open('a.txt','r',encoding='utf-8')
print(f.readline())
print(f.readline())
print(f.readline())
print(f.readline())
执行结果:a
b
c
d
比较:f.readline()与f.readlines()的区别,前者指一行,后者指的是所有的元素(将文件中的从当前指针开始往后的所有行的每一行作为一个元素,一次性显示)
f = open('a.txt','r',encoding='utf-8')
print(f.readline())
print(f.readlines())
-------->
a
['b\n', 'c\n', 'd\n', 'e\n', 'f\n', 'g\n', 'h\n']
for i in range(5): ------------------ 利用for循环来避免代码的重复
print(f.readline())
读第5行到第10行:for循环中加if判断
打印所有,循环每一行
f = open('a.txt','r',encoding='utf-8')
for i in f.readlines():
print(i)
---->
a
b
c
d
e
f
g
h
打印出来后会每行都带一个换行符,因为每个元素后带有\n,若要消除这个换行符,就要用strip参数
f = open('a.txt','r',encoding='utf-8')
for i in f.readlines():
print(i.strip())
将第五行不打印,打印成“----------------++++++==============”
f = open('a.txt','r',encoding='utf-8')
for index,i in enumerate(f.readlines()):
if index == 4:
print('=============')
continue
print(i.strip()) ---------------> 这样打印出来的就是纯的i参数。i代表了Readlines的值
--------->
a
b
c
d
=============
f
g
h
4,实例:
count = 0
for line in f: --------->文件中的每一行作为元素来执行循环。
if count == 9:
print('-----------55555------')
count +=1
countinue
print(line)
count +=1
5,查看文件句柄中的指针(光标)所在的位置(以字符作为计数单位,每行结尾一个结束符,也算一个字符):tell
f = open('a.txt','r',encoding='utf-8')
print(f.tell()) ----------最开始为0
print(f.readline()) ---------- a
print(f.tell()) ---------- 3
print(f.readline()) ---------- b
print(f.tell()) ------------ 6 tell是按字符数来计算的
打印文档的前6个字符:
f = open('aa','r',encoding = 'utf-8')
print(f.read(6))
--->
dss
ss
f = open('a.txt','r',encoding='utf-8')
print(f.read()) --------- 读a.txt文件里所有的内容
print(f.read(5)) ---------- 只读a.txt文件里的前5个字符!!!!!!
f = open('a.txt','r',encoding='utf-8')
print(f.read(9))
a a之后有一个\n,也算是一个字符
b b后面也是一个换行符,每一行的结尾都有一个换行符,占用一个字符的位置。
c
d
e
echo 'asdcddeffssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss' >a.txtf
f = epen('a.txt','r',encoding='utf-8')
print(f.tell()) ------------- 0
print(f.read(50))
print(f.tell()) ------------> 50 (注意:此处的指针和读取了字符数相同,建立在第一行的字符足够多,若发生了换行,则两者的数量不相同 )
f = open('a.txt','r',encoding='utf-8')
print(f.read(9))
print(f.tell())
----->
aeeeeeeee
9
将指针从文件中某位置再回到0:seek(0)
seek有个适用范围,当为终端设备文件(tty)时,seek命令无效。它是无法按照字符的长度去移动的。
f = open('a.txt','r',encoding='utf-8')
print(f.read(9))
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
f.seek(0)
print(f.tell()) -----------> 0
echo 123456789 > /a.txt
f = open('a.txt','r',encoding='utf-8')
f = open('a.txt','r',encoding='utf-8')
f.seek(5)
python读文件不是自己去读,而是调用操作系统自身的接口,IO去读的,该接口程序不光给python打开文件,还会为其他程序也打开文件,内部自动维持了一个列表。读文件会分配一个内存编号,查看该内存编号:
f = open('a.txt','r',encoding='utf-8')
print(f.fileno())
判断文件是否可读:readable()
f = open('a.txt','r',encoding='utf-8')
print(f.readable())
----> True
判断文件是否可读写:
f = open('a.txt','r',encoding='utf-8')
print(f.readable())
print(f.writable())
---->
True
False
f = open('a.txt','w',encoding='utf-8')
print(f.readable())
print(f.writable())
----->
False
True
打印文件名:
f = open('a.txt','w',encoding='utf-8')
print(f.name)
---->
a.txt
实时将在内存中运行的python程序内容写到硬盘上,防止突然断电:f.flush()
f = open('a9.txt','w',encoding='utf-8')
f.write('hello1\n')
f.write('hello2\n')
f.write('hello3\n')
此时查看a9.txt,发现无内容
f.flush()
此时再查看a9.txt, 发现有内容了,此操作在pycharm里面可能实验不成功,在命令行窗口里成功
实例:
打印进度条:#####################################
print(‘#’),默认自动换行,所以不能用print
import sys
for i in range(50):
sys.stdout.write('#') ------->一次性打印50个#,stdout:标准输出,就是输出到屏幕。
import sys,time -------------> 每隔0.5秒执行一次,要加入time模块
for i in range(50):
sys.stdout.write('#')
time.sleep(0.5)
上述代码可以写成:
import sys,time
for i in range(50):sys.stdout.write("#"),time.sleep(0.5)
注意:不会每个的显示出来。还是会等全部执行完成后一次性显示出来,即要等一段时间(代码全部运行完成后)
所以要实现动态的一个个的打印#号就得不停的写入硬盘:
import sys.time
for i in range(50):
sys.stdout.write('#')
print(f.flush())
time.sleep(0.5)
truncate :截断(参数必需用‘a’,而不能用‘w’,否则清空了原文件)
f = open('a9.txt','w',encoding='utf-8')
f.truncate() -------->会清空a9.txt
f = open('a9.txt','a',encoding='utf-8') ------> 注意:这里用a,若用w就表示清空了a9.txt这个文件里,后面的截断后的效果就是留了几个空格。
f.truncate(10) ----------------------------->从文件开头,前10个字符,开始截断,后面的不要。
f = open('a9.txt','a',encoding='utf-8')
f.seek(10) -----------------------------先指定光标的起点
f.truncate(20) -----------------再从指定的指针开始截断,注意:截断是保留断点的前面部分,断点后面的部分不要
文件修改:
f = open('a.txt','r',encoding='utf-8')
f_1 = open('a1.txt','w',encoding='utf-8')
for line in f.readlines() ---------------------->可以改成:for line in f:
if "肆意的快乐" in line:
line = line.replace("肆意的快乐等我享受",“aaaaaa”)----------->注意:不能用f.replace()
f_1.write(line)
f.close()
f_1.close()
6,with语句:避免打开文件后忘记关闭。
with epen ('a.txt','r',encoding='utf-8') as f:
for line in f:
print(line)
此时不需要写f.close(),with xh
可以同时打开多个文件:
with open('x.txt') as a1,open('y.txt') as a2:
python的一行代码不应该超过80个字符,打开多个文件的规范写法:
with epen ('a.txt','r',encoding='utf-8') as f,\
epen ('b.txt','r',encoding='utf-8') as f1:
7,字符编码与转码,中间纽带:Unicode
Unicode ————encode ————> utf-8
<------- decode ---------
Unicode ------encode ---------> gbk
<-----decode----------
查看系统的默认编码:
import sys
print(sys.getdefaultencoding())
8,函数
编程方式:
1,面向对象:类 ---- class
2,面向过程,过程 --- def
3,函数式编程,函数 ---- def
函数式逻辑结构化和过程化的一种编程方法,先定义一个数字函数,然后按照这个数学模型用编程语言去实现它,
函数实例:
def test(x): ------------------------- def 定义函数的关键字,test 函数名, ()内可定义形参
"The function definitions" --------------- 文字描述,非必要,但建议要有
x+=1 ----------------------------------- 泛指代码块或程序处理逻辑
return x ---------------------------------- 定义返回值
....................................................
def func1():
"""flsjfs lsjfsjf f ajflj"""
print('in the func1')
return 0
过程实例1:--------------------------------------- 过程就是没有返回值的函数而已
def func2():
'''testing2'''
print('in the func2')
调用方法:
x=func1() ----------------
y=func2()
print(x) ----------------返回:0
print(y) ----------------返回:None
实例2:
def test1():
print('in the test1')
def test2():
print('in the test2')
return 0
def test3():
print('in the test3')
return 1,'hello',['alex','wupeiff'],{'name':'alex'}
x=test1()
y=test2()
z=test3()
print(x)
print(y)
print(z)
---->
in the test1
in the tset2
in the test3
None
0
(1,'hello',['alex','wupeiff'],{'name':'alex'}) 将多个值装到一个元组当中,一下子全返回的是一个元组:tuple
返回值的作用:检测到这个函数整个执行的一个结果,里面可以写上1万行代码,可以根据返回值来进行后面的操作。
实例3:带参数的函数:
def test(x,y): ---------------》 x ,y 叫做形参 ,形式上的参数或者名义上的参数,要被替换的参数
print(x)
print(y)
test(1,3) ----->直接运行test()会出错,1,3叫做实参:实际中测占用空间的参数
----> pycharm 运行(不加注明的话,都是在pycharm里运行)
1
3
说明:形参和实参一一对应
def test(x,y):
print(x)
print(y)
test(y=1,x=2) ----------- >这里给x和y赋值时,可以是位置参数调用,直接用值,此时赋值要求和形参前后顺序一一对应,也可以是关键字调用,赋值表达式,此时不受前后顺序的影响
---->
2
1
...............................
def test(x,y):
print(x)
print(y)
x=1
y=2
test(y=y,x=x) 这里的y=y,第一个y代表形参的y,第二个y代表内存中实际的赋值2,可以写成:test(y=2,x=1)
----->
1
2
也可以写成:
def test(x,y):
print(x)
print(y)
a=1
b=2
test(y=b,x=a)
def test(x,y):
print(x)
print(y)
test(x=2,3) --------->此时执行会报错
test(2,y=3) --------->此时能运行。
一句话:当既有关键参数,又有位置参数时,关键字参数是不能写在位置参数前面的,违反这个就报错
def test(x,y,z)
test(3,y=2,6)就可以 test(3,5,y=4)这样也报错,因为没有值赋给z了
test(3,y=2,8)就报错
test(3,z=3,y=4)这样也可以的,
默认参数:
def test(x,y=3):
print(x)
print(y)
test(1) ----------------------此时没有赋值给y,就采用默认的值
----->
1
3
def test(x,y=3):
print(x)
print(y)
test(1,3)
------》 ------------------=-- 当有值赋给y时,就会采用赋给的值,调用函数时优先采用实参,当实参缺失时就采用默认的值
1
3
用途:默认安装软件时的路径,默认值。
参数组:
def test(*args): -------------------- * 以星号开头,代表后面的args的变量的个数是不固定的。args是一个变量名,可以随便取
print(args) 一般都args来表示,规范都用args
test(1,2,3,4,5)
---->
(1,2,3,4,5) ------------------- 全部放到一个元组里面。
test(*[1,2,3,4,5]) ----------此时用*加一个列表的方式来参数
---->
(1,2,3,4,5)
def test1(x,*args)
print(x)
print(args)
test(1,2,3,4,5,6,7)
---->
1
(2,3,4,5,6,7)
应用:给一个函数传一个不固定的参数时用这个
**kwargs:把n个关键字参数转化成字典的方式
def test2(**kwargs):
print(kwargs)
test2(name='logy',age=9,sex='sfsf') ------都是关键字参数, 将关键字参数转化成字典
---->
{'name':'logy','age':9,'sex':'sfsf'}
实例:
def test2(**kwargs):
print(kwargs)
print(kwargs['name']) ----------------可以直接取出字典里的值
print(kwargs['age'])
print(kwargs['sex'])
test2(name='logy',age=9,sex='sfsf')
实例:
def test3(name,**kwargs):
print(name)
print(kwargs)
test('alex')
---->
alex
{}
def test3(name,**kwargs):
print(name)
print(kwargs)
test('alex','afasf')
---->运行会报错。因为**kwargs只能是关键字参数
def test3(name,**kwargs):
print(name)
print(kwargs)
test('alex',age=23,sex='fsff',ff=564)
---->
alex
{'age':23,'sex':'fsff','ff'=564}
参数组有两种形式:
1,接收 *args 当成元组的形式
2,接收**kwargs ,当成字典的形式
实例:
def test4(name,**kwargs,age=18) ------ 写法错误,参数组一定要放到最后面
def test4(name,age=18,**kwargs) ---- 对了
print(name)
print(age)
print(kwargs)
test4('alex',sex='b',hobby='sfsf',klk=56)
---->
alex
18
{'sex':'b','hobby':'sfsf','klk':56}
实例:
def test4(name,age=18,**kwargs) ---- 对了
print(name)
print(age)
print(kwargs)
test4('alex',sex='b',hobby='sfsf',klk=56,age=189) 注:test('alex',654,hobby='sfsf',klk=56,age=189)此时运行后报错,说明:参数名不能和参数组里的参数名相同,会提示有多个值给
-----> age,相当于给age赋值了两次,而违反了实参和形参一一对应的关系
alex
189
{'sex':'b','hobby':'sfsf','klk':56}
实例:给默认参数赋值的形式:
def test(x,y=3,z)
test('adf',90000000,'sfsf')
test('adf','sfsf')
test('adf','sfsf',y=8)
实例:
def test4(name,age=18,*args,**kwargs)
print(name)
print(age)
print(args)
print(kwargs)
test4('alex',564,sex='b',hobby='sfsf',klk=56)
------->
alex
564
() ------------------------------------- *args接收不到关键字参数,只能接收位置参数(1,2,3,...n),转换成 元组的形式 ,此时接收不到就是空,故返回()
{'sex':'b','hobby':'sfsf','klk':56} ----- **kwargs,接收关键字参数,转化成字典的形式
python调用是从上到下的顺序:
def test1(x,y)
print(x)
logger('test4')
test1(3,4)
def logger(source):
print("from %s"% source)
此时执行会报错,提示找不到logger,应该为:
def test1(x,y)
print(x)
logger('test4')
def logger(source):
print("from %s"% source)
test1(3,4)
10,局部变量
例1
def chang_name(name):
print("before change",name)
name="ALEX" -----------------------这个值是在函数里面赋值的,只在该函数范围为起作用,该值就是一个局部变量,该函数就是这个函数的作用域,出了这个域就无效
print("after change",name)
name='alex'
change_name(name)
print(name)
------>
before change alex
after chang ALEX
alex
例2:
def a(x):
print(x)
y=98
a(34)
print(y)
此时运行会报错,因为y的值找不到。因为y=98只在函数内部生效,出了该函数,y就没有值了
全局变量:在整个程序中都生效的变量,在代码的顶层定义的变量都是全局变量,在函数里面可以直接访问。
例3:
school = 'aaaaa'
def a(x):
print(x)
print(school)
a(1)
school = 'aaaaa'
def a(x):
school = "+++++++++++++++++++++++++"
print(x)
print(school)
a(1)
print(school)
函数里的该全局变量:
school = 'aaaaa'
def a(x):
global school -----------------------------声明将school变量改成全局生效
school = "+++++++++++++++++++++++++"
print(x)
print(school)
a(1)
print(school)
实际中在现实中,不能再函数里用global,更不能在函数去创建一个全局变量,违反行规,全局变量一定要在顶层定义的
def a():
global aaaa
aaaa = '888888888'
a()
print(aaaa) -----------------------------尽管这个方法可以创建一个全局变量,但不能用
应用范围:只有简单的字符串和整数只能在函数里生效
其他,字典,列表,集合,类等在函数里定义了,其生效范围会扩大到整个全局的
实例:
names = ['alex','jacke','rani']
def a():
names[0] = "复数"
print("inside func",names)
a()
print(names)
---->
inside func ["复数", 'jacke','rani']
["复数", 'jacke','rani']
11,递归
在函数内部,可以调用其他函数,如果一个函数在内部调用自身本身,这个函数就是递归函数
特性:1,要有一个明确的结束条件(最大的递归次数999次)
2,每次进入更深一层的递归时,问题的规模相比上一层都应有所减少
3,递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈stack这种数据结构来实现的,每当进入一个函数调用
栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,由于栈的大小不是无限的,所以递归层次过多,会导致栈溢出 )
计算机中:有栈和堆这两种概念
没有限制条件的递归函数
def calc(n):
print(n)
return calc(n+1)
calc(0)
def calc(n):
print(n)
if n/2 >0:
return calc(n/2)
calc(10)
def calc(n):
print(n)
if int(n/2) >0:
return calc( int(n/2) )
calc(10)
def calc(n):
print(n)
if int(n/2) >0:
return calc( int(n/2) )
print('======',n)
calc(10)
---->
10
5
2
1
====== 1
12,函数式编程(记住一句话:这个函数式编程不是我们用的函数就够了)
更接近于数学计算,由于汇编语言时最贴近计算机的语言,计算则是数学意义上的计算,越是抽象的计算,离计算机硬件越远
对应到编程语言,越贴近于计算机,抽象程度低,执行效率高,比如C语言
越高级的语言,越贴近于计算,抽象程度高,执行效率低
函数式编程就是一种抽象程度高的编程范式,,纯粹的函数式编程语言编写的函授没有变量,因此,任意一个函数,只要输入时确定的,输出就是确定的。
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
函数式编程中的函数这个术语不是指计算机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候调用,调用几次,值都是不变的。
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
一、定义
简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
主要思想是把运算过程尽量写成一系列嵌套的函数调用。
举例来说,现在有这样一个数学表达式:
(1 + 2) * 3 - 4
传统的过程式编程,可能这样写:
var a = 1 + 2;
var b = a * 3;
var c = b - 4;
函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:
var result = subtract(multiply(add(1,2), 3), 4);
这段代码再演进以下,可以变成这样
add(1,2).multiply(3).subtract(4)
这基本就是自然语言的表达了。再看下面的代码,大家应该一眼就能明白它的意思吧:
merge([1,2],[3,4]).sort().search("2")
因此,函数式编程的代码更容易理解。
要想学好函数式编程,不要玩py,玩Erlang,Haskell, 好了,我只会这么多了。。。
现在最好的编程范式是:面向对象
13,高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
返回值带有另外一个函数的函数名也是高阶函数
def add(x,y,f):
return f(x) + f(y)
res = add(3,-6,abs)
print(res)
例2:该例不是高阶函数
def add(a,b)
return a+b
例3:该例就是高阶函数
def add(a,b,f)
return f(a)+(b)
res = add(-3,-6,abs)
print(res)
python基础之3的更多相关文章
- python之最强王者(2)——python基础语法
背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...
- Python开发【第二篇】:Python基础知识
Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...
- Python小白的发展之路之Python基础(一)
Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...
- Python之路3【第一篇】Python基础
本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...
- 进击的Python【第三章】:Python基础(三)
Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...
- 进击的Python【第二章】:Python基础(二)
Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...
- Python之路【第一篇】python基础
一.python开发 1.开发: 1)高级语言:python .Java .PHP. C# Go ruby c++ ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...
- python基础之day1
Python 简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python为我们提供了非常完善的基础代码库,覆盖了 ...
- python基础之文件读写
python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...
- python基础之编码问题
python基础之编码问题 本节内容 字符串编码问题由来 字符串编码解决方案 1.字符串编码问题由来 由于字符串编码是从ascii--->unicode--->utf-8(utf-16和u ...
随机推荐
- JS 对象的属性如果没有就初始化
function fuck (inObj, path, parms) { // 一个长得像对象的字符串 var Things = path.split("."); // 即将返回的 ...
- AutoFac文档14(转载)
目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 激活事件 在compo ...
- WiX and System Folders 系统目录 installshield 如何将文件安装到C盘根目录
Property name Brief description of property AdminToolsFolder Full path to the directory containing a ...
- jquery常见插件用法表
一:美化select表单:chosen.jquery.js http://harvesthq.github.io/chosen/ 关于ajax更新列表后需要触发下插件的事件,才会表现出来:(http: ...
- atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结
atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结 1. 为什么虚拟机语言容易被反编译 1 2. 源码泄露的问题问题 1 3. Excelsior JET 1 4. gcj.的流 ...
- Struts2初学 Struts2在Action获取内置对象request,session,application(即ServletContext)
truts2在Action中如何访问request,session,application(即ServletContext)对象???? 方式一:与Servlet API解耦的方式 可以使用 ...
- MySQL编码问题集合
1.以root用户的身份登录,查看编码设置 mysql> SHOW VARIABLES LIKE 'character%'; +--------------------------+------ ...
- Codeforces461A Appleman and Toastman 贪心
题目大意是Appleman每次将Toastman给他的Ni个数拆分成两部分后再还给Toastman,若Ni == 1则直接丢弃不拆分.而Toastman将每次获得的Mi个数累加起来作为分数,初始时To ...
- DDR2基础
一. DDR2介绍 DDR2由JEDEC(电子设备工程联合委员会)开发的新生代内存技术标准.该标准定义了DDR2封装.寻址及操作.电气等所有特性. DDR相关技术对比 DDR DDR2 DDR3 电压 ...
- 实战c++中的vector系列--知道emplace_back为何优于push_back吗?
上一篇博客说道vector中放入struct.我们先构造一个struct对象.再push_back. 那段代码中,之所以不能使用emplace_back,就是由于我们定义的struct没有显示的构造函 ...