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('++++++++++++++++++++++ ')
f.write('======================')
------>会在当前路径创建一个 bb.txt 的文件: ++++++++++++,
============
追加模式:a
f = open('bb.txt','a','encoding=utf-8')   ----------------》注意此时的a模式下只能写,而不能读,后面接读的操作会报错,若为不存在的新文件则创建
f.write('++++++++++++++++++++++ ')
f.write('======================')
f.write('aaaaaaaaaaa ')
f.write('vvvvvvvvvvv')
f.close
会沿着之前的文件内容接着写,不会冲掉之前的内容,此时仍然不能读,一读就报错。

注意:a模式也可以创建新文件
f = open('cc','a',encoding = 'utf-8')
f.write(' +++++++++++++++++')
f.write(' -----------------')
f.write(' 55555555555555555')
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 ', 'c ', 'd ', 'e ', 'f ', 'g ', 'h ']

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

打印出来后会每行都带一个换行符,因为每个元素后带有 ,若要消除这个换行符,就要用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之后有一个 ,也算是一个字符
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)        ------------------>此时光标(指针)就会自动到第⑤个字符后去
print(f.readline())
#print(f.read(9))
---->
6789


python读文件不是自己去读,而是调用操作系统自身的接口,IO去读的,该接口程序不光给python打开文件,还会为其他程序也打开文件,内部自动维持了一个列表。读文件会分配一个内存编号,查看该内存编号:
f = open('a.txt','r',encoding='utf-8')
print(f.fileno())   --------用得少
------>
3

判断文件是否可读: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 ')
f.write('hello2 ')
f.write('hello3 ')
此时查看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)

 

原文地址:https://www.cnblogs.com/kaishirenshi/p/8629314.html