学习Python---Day3

学习内容:

一、集合操作

二、文件操作

三、字符编码与转码

四、函数与函数式编程

五、递归操作

一、集合操作

  集合是一个无序的,不重复的集合,主要作用:

     (1)去重复,把一个列表变成集合,就自动去重了

     (2)关系测试,测试两组数据之前的交集,差集,并集等关系

#集合 去重复 关系测试
list_1 = [1,4,5,7,3,7,9]
list_1 = set(list_1)  #列表变集合

list_2 = set([2,5,4,33,55,6])
print(list_1,list_2)

#关系测试
#交集
list = list_1.intersection(list_2)
print(list)


#并集
list_u = list_1.union(list_2)
print(list_u)

#差集  in list_1 but not in list_2
list_d = list_1.difference(list_2)
print(list_d)

#子集
list_issub = list_1.issubset(list_2)
print(list_issub)

list_3 = set([1,3,4])
print(list_3.issubset(list_3))

#父集
list_issup = list_1.issuperset(list_2)
print(list_issup)
print(list_1.issuperset(list_3))

#对称差集    把互相都没有的取出来
print(list_1.symmetric_difference(list_2))

print("-------------")
#是否有交集 没有是true,有时false
list_4 = set([5,6,7])
print(list_3.isdisjoint(list_4))


#交集
print(list_1 & list_2)
#并集 union
print(list_1 | list_2)

#差集 difference
print(list_1 - list_2)  #in list_1 but not in list_2

#对称差集
print(list_1 ^ list_2) #项在list_1 或list_2中,但不会同时出现在二者中

#添加
list_1.add(99)
print(list_1)

list_1.update([23,94,35]) #添加多项
print(list_1)

#删除
list_1.remove(23)
print(list_1)

#长度
print(len(list_1))

print(list_1.pop()) #删除任意的,并返回

#list_1.discard() #Remove an element from a set if it is a member.  If the element is not a member, do nothing.
print(list_1.discard("ddd"))

二、文件操作

     文件操作的流程:

    (1)打开文件,得到文件句柄并赋值给一个变量

  (2)通过句柄对文件进行操作

     (3)关闭文件

    现有文件如下:

白雪发亮今夜铺满笑声
没有脚印的地方
孤立的王国很荒凉
我是这里的女皇
风在呼啸像心里的风暴一样
只有天知道我受过的伤
别让他们进来看见
做好女孩就像你的从前
躲藏不让他们看见已被发现
随它吧随它吧
回头已没有办法
随它吧随它吧
一转身不再牵挂
我不管他们想说的话
任风吹雨打
反正冰天雪地我也不怕
这一点点的距离
让一切变精致
曾经困扰我的恐惧
会远离我回忆
现在开始让我看见
是我的突破和极限
不分对错没有极限
向前
随它吧随它吧
跟风和天空对话
随它吧随它吧
眼泪不再掉下
这个家
让我留下
任风吹雨打
Let it go let it go
让我在曙光中升华
Let it go let it go
让完美被蒸发
这个家
在阳光之下
任风吹雨打
反正冰天雪地我也不怕

具体操作如下:

f = open("LRC",'a',encoding="utf-8")  #文件句柄(内存对象)
#a = append 追加 不会冲掉之前的内容
#r = read 读所有
#w = write 写会把之前的文件内容全部冲掉
data = f.read()  #读取所有内容,文件太大时不要使用

print(data) #打印文件
f.close() #关闭
f = open("LRC",'r',encoding="utf-8")  #文件句柄(内存对象)
print(f.tell())  #光标位置
print(f.readline())   #读一行
print(f.tell()) #光标移到第二行,同时打印第一行的字符个数

f.seek(0) #0返回最开始
print(f.readline())

print(f.encoding)  #打印编码格式

print(f.fileno())  #返回一个编号

#print(f.flush()) #刷新,一般默认是内存满了自动刷
f = open("LRC",'r',encoding="utf-8")  #文件句柄(内存对象)
#low loop (读到第九行打印) 列表
for index,line in enumerate(f.readlines()):
    if index == 9:
        print('---分割线---')
        continue
    print(line.strip())

f = open("LRC",'r',encoding="utf-8")  #文件句柄(内存对象)
#一行一行读,内存只保存一行 high bige  效率高  不是列表了
count = 0
for line in f:
    if count == 9:
        print('---分割线---')
        count += 1    #count = 10 如果没有这一行continue之后会一直是9
        continue
    print(line)
    count += 1

f = open("LRC",'w',encoding="utf-8")  #文件句柄(内存对象)
f.write("hello\n")
f.flush()  #实时刷
f.write("hello1")
f.write("hello\n")
f.flush()

f = open("LRC",'a',encoding="utf-8")  #文件句柄(内存对象)
#f.truncate()#截断 不指定从0开始
f.seek(10)
f.truncate(10) #seek不管用,都是从0开始截断  即是从开始截断


f = open("LRC",'w+',encoding="utf-8")  #文件句柄(内存对象)
print(f.write("----a----\n"))
print(f.write("----b----\n"))
print(f.write("----c----\n"))
print(f.write("----d----\n"))
print(f.tell()) #打印位置
f.seek(2)
print(f.readline())
f.write("should be at the ")

f.close()

#r+ 读写  既能读又能写  以追加的形式添加
#w+ 写读  先创建一个文件在写
#a+ 追加读写
#rb 二进制文件
f = open("LRC",'wb')  #文件句柄(内存对象)
#rb 二进制读
#wb 二进制写

#print(f.readline())
#print(f.readline())
#print(f.readline())

f.write("hello binary\n".encode()) #encode()字符转二进制 以二进制编码的
f.close()

总结:

 基本的打开模式:

  (1)r = read  只读(默认)

  (2)w = write 只写 (不可以读,如果不存在则创建;如果存在则把文件中的内容全部冲掉)

  (3)a = append 追加(可读,如果不存在则创建;如果存在则把添加的内容追加到文件中)

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

    (1)r+,可读文件(可读,可写,可追加)

    (2)w+,可读,可写

    (3)a+,追加读写

    “U”表示在读取时,可以将\r\n\r\n自动转换成\n (与r和r+使用相同)

     (1)rU

     (2)r+U

    “b”表示二进制文件

     (1)rb 二进制读

     (2)wb二进制写

案例:
#文件修改
#vim 把文件读到内存中
# 或者写到新文件中

f = open("LRC",'r',encoding="utf-8")  #文件句柄(内存对象)
f_new = open("LRC.new","w",encoding="utf-8")
'''
for line in f:
    if "让我留下任风吹雨打"in line:
        line = line.replace("让我留下任风吹雨打","让ME留下任风吹雨打")
        f_new.write(line)
    else:
        f_new.write(line)
'''
#或者
for line in f:
    if "让我留下任风吹雨打"in line:
        line = line.replace("让我留下任风吹雨打","让ME留下任风吹雨打")
    f_new.write(line)

f.close()
f_new.close()

三、字符编码与转码

       Unicode 中文和英文都占2个字节(16位) ACSSII英文站1个字节(8位)

  在python3中默认使用unicode

  Unicode支持utf-8和gbk,但是必须经过编码和转码才行

  注:字符串是不可以修改的  (可以变大小写,是更新生成新的数据)

 

#-*- coding:utf-8 -*-
s = "你好"

s_gbk = s.encode("gbk")
print(s_gbk)
print(s.encode())  #默认是utf-8

gbk_to_utf8 = s_gbk.decode("gbk").encode("utf-8") #gbk先转unicode(包含中文和英文),再转utf-8
print("utf-8",gbk_to_utf8)
#-*-coding:gbk-*-#

import  sys

print(sys.getdefaultencoding())

s = "你哈"  #unicode
print(s.encode("gbk"))
print(s.encode("utf-8"))

ss = s.encode("utf-8").decode("utf-8")

四、函数与函数式编程

编程方式:

(1)面向对象:类---》》class

(2)面向过程:过程---》》def

(3)函数式编程:函数---》》def

函数好处:

(1) 代码的重复利用(减少重复代码)

(2) 保持一致性 (易维护)

(3)  可扩展

函数返回值:

返回值数=0,返回None

返回值数=1;返回object

返回值数>1;返回tuple

函数参数与局部变量:

形参:形参变量只有咋被调用时才分配内存单元,调用结束,即释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不        能在使用该形参变量。

实参:可以是常量、变量、表达式、函数等,无论是参数是何种类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传送给形参。因此应预        先用赋值,输入等办法使参数获得确定值。

全局与局部变量:

  在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
  全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
  当全局变量与局部变量同名时:
  在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

案例:

#函数
def func1():
    "testing 文档介绍"
    print('in the func1')
    return 0

#过程   没有返回值的函数
def func2():
    "testint2  文档介绍"
    print('in the func2')

x = func1()
y = func2()

print('from func1 return is %s' %x)
print('from func2 return is %s' %y)
#添加时间
def logger():
    time_format = '%Y-%m-%d %X'
    time_current = time.strftime(time_format)
    with open('LRC','a+') as f:  #打开文件yesterday.txt,并以二进制追加的方式ab
        f.write('%s end action\n' %time_current)  #在文件中写字符串

def test1():
    print('test1 staarting action......')
    logger()
def test2():
    print('test2 staarting action......')
    logger()
def test3():
    print('test3 staarting action......')
    logger()

test1()
test2()
test3()
def test1():
    print('in the test1')

def test2():
    print('in the test2')
    return 0

def test3():
    print('in the test3')
    return 1,'hello',['zhang','li'],{'name','age'}

x=test1()
print(x)
y=test2()
print(y)
z=test3()
print(z)
#有参数
def test(x,y):  #x,y形参  未知参数
    print(x)
    print(y)

test(1,2)  #1,2实参  结果1  2  与形参一一对应

test(y=1,x=2)  #结果  2  1  与形参顺序无关

x=1
y=2 #定义内存对象
test(y=y,x=x)  #前面y是形参 ,后面y是对象2   关键字调用

#test(x=2,3) # 这是错误的  关键参数x是不能写在未知参数前面的
test(3,y=2) # 3,2
#默认参数
#特点:调用函数的时候,默认参数可有可无(非必传)
#用途:(1)默认安装值 (比如安装软件有的勾选了) (2)连接数据库端口号(比如mysql默认端口号3306)

def test(x,y=2):
    print(x)
    print(y)


x=test(1,y=3)
test(1,5)
def test(x,y,z=2):   #默认参数可有可无
    print(x)
    print(y)

test(1,2)

#参数组定义   实参不固定,形参应如何定义

def test1(*args):
    print(args)

test1(1,2,3,4,5)

test1(*[1,2,3,4,5,6])  #*args=*[1,2,3,4,5,6]  变成一个元组 args=tuple([1,2,3,4,5,6])

#结合位置参数
def test2(x,*args):
    print(x)
    print(args)

test2(1,2,3,4,5)

#接收字典  **kwargs:把N个关键字参数,转换成字典的方式
def test3(**kwargs):
    print(kwargs)
    print(kwargs['name'])
    print(kwargs['age'])

test3(name='ZhangSan',age=8) #关键字参数可以传递下去  name当成key
#同下面形式
test3(**{'name':'ZhangSan','age':8})

#与位置参数可否一起用
def test4(name,**kwargs):
    print(name)
    print(kwargs)

test4('LiSi')  #后面是个空字典
#test4('LiSi','xxxx') #错误,后面必须是关键字参数
test4('LiSi',age=21,sex='girl')

#*args 接收的是N个未知参数,转换成元组的形式,不能接收关键字参数
#**kwargs:接收的是N个关键字参数,转换成字典的方式

def test5(name,age=18,*args,**kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)
    logger("test5")

def logger(source):
    print("from %s" %source)
test5('LiSi',age=21,sex='girl',hobby='tesla')

五、递归操作

  在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

def calc(n):
    print(n)

    if int(n/2)>0:
        return calc(int(n/2))
    else:
        return 0


calc(10)

输出:
10
5
2
1

递归特性:

(1) 必须有一个明确的结束条件

(2) 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

(3)递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

 

猜你喜欢

转载自www.cnblogs.com/Sue-blog/p/9139996.html