目录

Day3 本节内容:

一、集合

二、文件操作

1.文件操作

2.修改文件:

3.with语句:

三、函数

1.函数定义

2.调用方法,形参与实参

3.局部变量与全局变量

4.递归函数

5.高阶函数


Day3 本节内容:

集合

文件操作

函数

一、集合

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

>去重,把一个列表变成集合,自动去重

>关系测试,测试两组数据之前的交集、并集、差集等关系

list1 = [0,2,4,6,8]
list1_JiHe = set(list1)
print(list1_JiHe,type(list1_JiHe))
#{0, 2, 4, 6, 8} <class 'set'>

list2 = [0,4,9,10,22,44]
list2_JiHe = set(list2)

1.
集合关系测试
交集,list1与list2都有的重复部分
print(list1_JiHe.intersection(list2_JiHe))
#{0, 4}

并集,list1与list2的元素组合到一起,重复的元素只留一个
print(list1_JiHe.union(list2_JiHe))
#{0, 2, 4, 6, 8, 9, 10, 44, 22}

差集,list1有,list2没有的部分;list1中去掉与list2重复的部分,然后只list1的元素组合
print(list1_JiHe.difference(list2_JiHe))
#{8, 2, 6}

对称差集,list1和list2重复的部分去掉,然后两个中的元素都组合到一起
print(list1_JiHe.symmetric_difference(list2_JiHe))
#{2, 6, 8, 9, 10, 44, 22}

子集,判断list1是否为list2的子集,返回False或True
print(list1_JiHe.issubset(list2_JiHe))

父集,判断list1是否为list2的父集,返回False或True
print(list1_JiHe.issuperset(list2_JiHe))


2.
运算符求集合关系
交集
print(list1_JiHe & list2_JiHe)

并集
print(list1_JiHe | list2_JiHe)

差集
print(list1_JiHe - list2_JiHe)

对称差集
print(list1_JiHe ^ list2_JiHe)


3.
集合的增删改查
list1_JiHe.add(100) #添加一项
list1_JiHe.update([100,101,102]) #添加多项
list1_JiHe.remove(100) #删除一项

二、文件操作

1.文件操作

file = open(file='txt',mode='r',encoding='utf-8')
# mode = r 可读;  r+ 读写,追加模式的写入;
# w 可写,光标位置在开头,写会覆盖掉原文件;  w+ 写读
# a 追加模式,在文件最后面追加写入;  a+ 追加读
# rb 二进制模式 可读,二进制文件无编码
# wb 二进制模式 可写
# ab 二进制模式 追加模式读写
# rU 在读取时可以将\r \n \r\n自动转换为\n

data = file.read() # 读取文件内容,可以指定字符个数读取内容
print(data)
file.readline() #读取一行内容
file.readlines() #读取文件内容,每一行当做一个元素存到列表中
file.write('我爱北京天安门') #文件写入
file.close() #文件关闭

注意操作文件有光标定位,光标会随文件操作而改变位置后执行后续的文件操作
print(file.tell()) #打印光标位置
file.seek(10) #将光标回到第10个字符的位置
print(file.encoding) # 打印文件编码
file.flush() # 强制实时刷新,默认会通过缓存j机制达到一定空间时再一起刷新
file.truncate(20) # 从文件开头第20个字符开始,后面内容清空;修改光标位置没有用

2.修改文件:

同时打开两个文件,读取原文件内容,写入到新文件中,同时判断需修改的内容 修改后再写入到新文件。# 直接写入方式不可行(如果要修改的内容和原位置内容字符长度不一样时,直接通过写入操作会覆盖掉原文件对应位置的其他内容,所以不可行。)

# 例:要将abc文件中的"I love you so much"修改为"I like you too"
f = open('abc.txt','r',encoding='utf-8')
f_new = open('abc.txt.bak','w',encoding='utf-8')
for line in f:
    if 'I love you so much' in line:
        line = line.replace('I love you so much','I like you too')
    f_new.write(line)
f.close()
f_new.close()

3.with语句:

为了避免打开文件后忘记关闭,with代码块执行完毕时,内部会自动关闭并释放资源

f = open('abc.txt','r',encoding='utf-8')

with open('abc.txt','r',encoding='utf-8') as f:
    pass

打开多个文件
with open('txt1') as obj1,open('txt2') as obj2:
    pass

三、函数

编程方式:

     1.面向对象 :类------class 定义

     2.面向过程 :过程------def 定义

          将每个功能模块用def定义出

     3.函数式编程(了解):函数------def 定义

         函数式编程,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。纯粹的函数式编程语言编写的函数没有变量,因此任意一个函数,,只要输入是确定的,输出就是确定的。Python对函数式编程提供部分支持。由于python允许使用变量,因此,python不是纯函数式编程语言。

1.函数定义

函数是逻辑结构化和过程化的一种编程方法。

函数是Python内建支持的一种封装,通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。优点:代码复用、保持一致性、可扩展性

函数定义方法:
def test(x):
    '''It is a test function'''
    x+=1
    return x

test(1) # 调用函数,1为传递的实参

# def 定义函数的关键字
# test 函数名称
# x 定义的形参
# '''xxxx......''' 文档描述,非必要
# x+=1  代码块或程序处理逻辑
# return 定义返回值

######################

函数即变量:定义函数相当于定义一个变量,将函数体在内存中指向一个地址。
def func():
    print('yes')

a = func() # 会调用函数,a为函数执行的结果
print(a)
# yes

b = func # 不会调用函数,b为函数的内存地址
print(b)
# <function func at 0x00000162FCCDE160>

2.调用方法,形参与实参

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

位置参数调用,实参与形参一一对应
test(1,2)

关键字调用,位置无需对应
test(y=2,x=1)

混合使用,注意关键字调用必须在位置参数后面
test(1,y=2)

默认参数,默认参数y非必须传递;未传递时才使用默认值
def test2(x,y=10):
    print(x)
    print(y)
test2(1) # 1 10
test2(1,3) # 1 3


非固定参数
参数组,*args ;用于传递的实参不固定时,把N个 位置参数 转换成元组
def test3(*args):
    print(args)
    print(args[1])
test3(1,2,3,4,5)
test3(*[1,2,3,4,5])
# (1, 2, 3, 4, 5)
# 2

参数组,**kwargs ;把N个 关键字参数 转换成字典
def test4(**kwargs):
    print(kwargs)
    print(kwargs['name'])

test4(name='XiZz',age=18)
test4(**{'name':'XiZz','age':18})
# {'name': 'XiZz', 'age': 18}
# XiZz

3.局部变量与全局变量

局部变量,定义在函数模块中,变量的作用域只在函数内部。

使用global,在函数内部声明全局变量,才可以修改(字符串、数字类型)

注意:如果是列表、集合、字典,无需global声明 直接可以在函数内部修改。

1.
name = 'XiZz'
def info():
    #global name
    name = 'Yy'

info()
print(name)
# XiZz

2.
name = 'XiZz'
def info():
    global name
    name = 'Yy'

info()
print(name)
# Yy

4.递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自己本身(递归函数机制最多调用999次,否则内存会无限占用),这个函数就是递归函数。

递归特性:

    *必须有一个明确的结束条件

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

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

递归函数举例:
# int(n/2)限制值为整数;否则n/2会一直大于0,循环999次后报错
def calc(n):
    print(n)
    if int(n/2) > 0:
        return calc(int(n/2))
    print('-->',n)

calc(10)

# 10
# 5
# 2
# 1
# --> 1

5.高阶函数

变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接受另一个函数作为参数(传递函数即其名称,并非函数体),这种函数就称之为高阶函数。

高阶函数举例: 
import time
def func1():
    time.sleep(3)
    print('in the func1')

def func2(func_name):
    print('------start------')
    start_time = time.time()
    func_name()
    stop_time = time.time()
    print('------stop------')
    print(f'the func1 run time is {stop_time-start_time} !')

func2(func1)

#输出
------start------
in the func1
------stop------
the func1 run time is 3.013516664505005 !
###



注意:func2(func1())方式是错误的,高阶函数是传递函数即其名称,并非函数体
错误举例:
import time
def func1():
    time.sleep(3)
    print('in the func1')

def func2(func_name):
    print('------start------')
    start_time = time.time()
    func_name
    stop_time = time.time()
    print('------stop------')
    print(f'the func1 run time is {stop_time-start_time} !')
func2(func1())
#输出
in the func1
------start------
------stop------
the func1 run time is 0.0 !
###