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的更多相关文章

  1. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  2. Python开发【第二篇】:Python基础知识

    Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...

  3. Python小白的发展之路之Python基础(一)

    Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...

  4. Python之路3【第一篇】Python基础

    本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...

  5. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  6. 进击的Python【第二章】:Python基础(二)

    Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...

  7. Python之路【第一篇】python基础

    一.python开发 1.开发: 1)高级语言:python .Java .PHP. C#  Go ruby  c++  ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...

  8. python基础之day1

    Python 简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python为我们提供了非常完善的基础代码库,覆盖了 ...

  9. python基础之文件读写

    python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...

  10. python基础之编码问题

    python基础之编码问题 本节内容 字符串编码问题由来 字符串编码解决方案 1.字符串编码问题由来 由于字符串编码是从ascii--->unicode--->utf-8(utf-16和u ...

随机推荐

  1. JS 对象的属性如果没有就初始化

    function fuck (inObj, path, parms) { // 一个长得像对象的字符串 var Things = path.split("."); // 即将返回的 ...

  2. AutoFac文档14(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 激活事件 在compo ...

  3. WiX and System Folders 系统目录 installshield 如何将文件安装到C盘根目录

    Property name Brief description of property AdminToolsFolder Full path to the directory containing a ...

  4. jquery常见插件用法表

    一:美化select表单:chosen.jquery.js http://harvesthq.github.io/chosen/ 关于ajax更新列表后需要触发下插件的事件,才会表现出来:(http: ...

  5. atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结

    atitit.商业版 源码保护 与 java本地原生代码转换 的方案总结 1. 为什么虚拟机语言容易被反编译 1 2. 源码泄露的问题问题 1 3. Excelsior JET 1 4. gcj.的流 ...

  6. Struts2初学 Struts2在Action获取内置对象request,session,application(即ServletContext)

    truts2在Action中如何访问request,session,application(即ServletContext)对象???? 方式一:与Servlet API解耦的方式      可以使用 ...

  7. MySQL编码问题集合

    1.以root用户的身份登录,查看编码设置 mysql> SHOW VARIABLES LIKE 'character%'; +--------------------------+------ ...

  8. Codeforces461A Appleman and Toastman 贪心

    题目大意是Appleman每次将Toastman给他的Ni个数拆分成两部分后再还给Toastman,若Ni == 1则直接丢弃不拆分.而Toastman将每次获得的Mi个数累加起来作为分数,初始时To ...

  9. DDR2基础

    一. DDR2介绍 DDR2由JEDEC(电子设备工程联合委员会)开发的新生代内存技术标准.该标准定义了DDR2封装.寻址及操作.电气等所有特性. DDR相关技术对比 DDR DDR2 DDR3 电压 ...

  10. 实战c++中的vector系列--知道emplace_back为何优于push_back吗?

    上一篇博客说道vector中放入struct.我们先构造一个struct对象.再push_back. 那段代码中,之所以不能使用emplace_back,就是由于我们定义的struct没有显示的构造函 ...