python笔记-3(编码、文件、集合、函数、递归)

编码

assic(只有英文及特殊字符)  gb2312(6700)    gbk(1995-21000)   gb18030(27000)   万国码:unicode

python2.x默认为assic编码

python3.x默认为utf-8编码

改变编码:#-*- coding:utf-8 -*-  (告诉py解释器,后面的代码用utf8来解释)

msg = "中国“

msg.decode(encoding="utf-8").encode(encoding="gbk")  先解码为unicode,然后在编码为gbk

python2

  1. py2里默认编码是ascii
  2. 文件开头那个编码声明是告诉解释这个代码的程序 以什么编码格式 把这段代码读入到内存,因为到了内存里,这段代码其实是以bytes二进制格式存的,不过即使是2进制流,也可以按不同的编码格式转成2进制流
  3. 如果在文件头声明了#_*_coding:utf-8*_,就可以写中文了, 不声明的话,python在处理这段代码时按ascii,显然会出错, 加了这个声明后,里面的代码就全是utf-8格式了
  4. 在有#_*_coding:utf-8*_的情况下,你在声明变量如果写成name=u"大保健",那这个字符就是unicode格式,不加这个u,那你声明的字符串就是utf-8格式
  5. utf-8 to gbk怎么转,utf8先decode成un

python3

  1. py3里默认文件编码就是utf-8,所以可以直接写中文,也不需要文件头声明编码了
  2. 你声明的变量默认是unicode编码,不是utf-8, 因为默认即是unicode了(不像在py2里,你想直接声明成unicode还得在变量前加个u), 此时你想转成gbk的话,直接your_str.encode("gbk")即可以
  3. 但py3里,你在your_str.encode("gbk")时,感觉好像还加了一个动作,就是就是encode的数据变成了bytes里,我擦,这是怎么个情况,因为在py3里,str and bytes做了明确的区分,你可以理解为bytes就是2进制流,你会说,我看到的不是010101这样的2进制呀, 那是因为python为了让你能对数据进行操作而在内存级别又帮你做了一层封装,否则让你直接看到一堆2进制,你能看出哪个字符对应哪段2进制么?
  4. 那你说,在py2里好像也有bytes呀,是的,不过py2里的bytes只是对str做了个别名(python2里的str就是bytes, py3里的str是unicode),没有像py3一样给你显示的多出来一层封装,但其实其内部还是封装了的。 这么讲吧, 无论是2还是三, 从硬盘到内存,数据格式都是 010101二进制到-->b'xe4xbdxa0xe5xa5xbd' bytes类型-->按照指定编码转成你能看懂的文字

编码应用比较多的场景应该是爬虫了,互联网上很多网站用的编码格式很杂,虽然整体趋向都变成utf-8,但现在还是很杂,所以爬网页时就需要你进行各种编码的转换,不过生活正在变美好,期待一个不需要转码的世界。

最后,编码is a piece of fucking shit, noboby likes it.

文件

 r:只读模式(默认)

 w:只写模式(不可读,文件不存在则创建,存在则覆盖原内容)

 a:追加模式(可读,文件不存在则创建,存在则只在文件末尾追加内容)

+表示可以同时读写某个文件

  r+:可读写文件(可读、可写、可追加)

  w+:写读(清空原文件,再写入新内容**尽量少用**)

  a+:同a

U表示在读取时,可以将 自动转换成 (与r或r+模式同时使用)

  rU

  r+U

b表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需注明)

  rb

  wb

  ab

-----------------------------------------------------------------------------------

f = open("test","r+",encoding="utf-8")

print("cursor:",f.tell())

print(f.read())

f.write("test")

f.close()

  open()#如果encoding不声明,默认使用操作系统的编码来解释文件

  f.tell()#光标所在位置

  f.seek(10)#将光标移动10个字节

  f.read(10)#读取10个字符

  f.flush()#将内存中的数据刷新至硬盘,一般用于打印实时日志

集合

name = {}

天生去重

关系运算

a = {1,2,3,4,5,6,7,}
b = {8,5,6,98,644,2,3}
#差集
print(a - b)
print(a.difference(b))
print(b - a)
print(b.difference(a))
##交集
print(b & a)
print(a.intersection(b))
print(b.intersection(a))
#并集
print(a | b)
print(a.union(b))
print(b.union(a))
#对称差集
print(a ^ b)
print(a.symmetric_difference(b))
print(b.symmetric_difference(a))

a = {1,2,3}
b = {1,2,3,4,5,6}
print(a.issubset(b)) #a是不是b的子集
print(a.issuperset(b)) #a是不是b的父集

函数

定义函数的三种形式:

1、无参函数:def foo(): print("in the foo")  调用时不用传参数:foo()

2、有参函数:def bar(x,y):print("in the bar")  调用时必须穿参数:bar(1,2)

3、空函数:def func():pass  用途:利用空函数制定好程序架构,然后再一个功能一个功能实现

调用函数的三种形式:

1 def foo():
2     print("in the foo")
3 
4 foo()
一、语句形式
1 def my_max(x,y):
2     if x>y:
3         return x
4     else:
5         return y
6 
7 my_max(1,2)
8 res = my_max(1,2)
9 res = 10*my_max(1,2)  
二、表达式形式
1 def my_max(x,y):
2     if x > y:
3         return x
4     else:
5         return y
6 
7 my_max(1,my_max(2,3))
三、作为另一个函数的参数

函数返回值的三种形式,返回值可以是任意的数据类型:

1 def foo():
2     pass
3 
4 res = foo()
5 print(res)
一、不返回(不定义返回值,则返回值为空(none))
二、返回一个(返回定义的值(1))
1 def foo():
2     return 1,'s',[1,2,3]
3 
4 res = foo()
5 print(res)
6 
7 结果:(1,'s',[1,2,3])
三、返回多个(以元组的形式返回定义的多个返回值[(1,'s',[1,2,3])])

函数的参数:形参,实参

def  name(x,y):    #name函数名字,(x,y)形参

  res = x**y

  return res       #return:1、返回函数结果;2、代表函数的结束

c = name(a,b)      #(a,b)实参

print(c)

def foo(x,y):------>形参,只有在函数调用时才会接收到值,等函数运行完毕后马上释放内存

  print(x)
  print(y)
foo(1,2)---------->实参,真正占用内存空间

实参:有确定值的参数,所有数据类型都可以当作参数传递给函数

形参:只有在被调用的时候才分配内存,调用后,立刻释放内存,值仅在函数内部有效(形参的作用域只在当前函数内部生效)

从实参的角度可分为:按位置的方式和按关键字的方式

按位置的方式:

def foo(x,y):

   print(x,y)

foo(1,2)

按关键字的形式:

def foo(x,y):

   print(x,y)

foo(y=2,x=1)

对同一个形参,我们要么按照位置要么按照关键字为形参传值,对同一个形参不能重复赋值

关键字的形式的参数只能放在位置参数的后面

从形参角度可分为:位置参数,默认参数,可变长参数,**kwargs

位置参数:def foo(x,y,z)  也是必传参数,不能多也不能少

默认参数:def foo(x,y,z=1) z就是默认参数,调用时不是必须赋值

 

--------------------------------------------

def change(a):
print(a) #引用全局变量
a = "syan" #局部变量
print(a)

b = "bob" #全局变量
print(b)
change(b)
print(b)
全局变量默认不能被函数内部(局部变量)修改,只能引用
如果想在函数内部修改全局变量,需要在函数内部声明:global,但是强烈建议不这么使用
----------------------------------
def change():
print(names)
names[0] = "Mack"
names.append("lili")
info["age"] = 22
names = ["bob","tom"]
info = {"syan":"rain"}
change()
print(names,info)

结果:
['bob','tom']
['Mack','tom','lili']{'syan':'rain','age':22}

函数内部可以修改列表、字典、集合、实例(类)

位置参数:必须按顺序传入

默认参数:

关键参数:

默认参数和关键参数必须放在位置参数后面

非固定参数:*args = ()以位置参数的形式传人,**kwargs = {}以关键参数的形式传人

匿名函数:(labmda)

def calc(x,y):
return x**y
print(calc(10,12))

calc2 = lambda x,y:x**y
print(calc2(10,12))

匿名函数最复杂的运算就是三元运算:

def calc(x):
if x > 5:
return x*2
else:
return x-1
for i in map(calc,[1,2,3,4,5,6,7,8,9]):
print(i)

 

for i in map(lambda x:x*2 if x>5 else x-1,[1,2,3,4,5,6,7,8,9]):
print(i)

高阶函数:

def add(x,y,f):
return f(x) + f(y)

print(add(3,-5,abs))
abs为内置函数
函数在调用时不加(),则会调其内存地址

1、把一个函数的内存地址传给另一个函数当做参数

2、一个函数把另一个函数当做返回值返回

递归

def calc(n):
print(n)
if int(n/2)>0:
n = calc(int(n/2)) #将每层的结果赋值给n
print(n)
return n
print(calc(10))
可以得到最里层的值

特性:
必须有一个明确的结束条件
每次进入更深一层递归时,问题规模相对上一次递归都应有所减少
递归效率不高,递归层次过多会导致栈溢出

 

原文地址:https://www.cnblogs.com/super-sos/p/6366744.html