Python全栈开发记录_第四篇(集合、函数等知识点)
知识点1:深拷贝和浅拷贝
- 非拷贝(=赋值:数据完全共享,内存地址一样,修改一个另一个也变化)
- 浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)像[[1,2],3,4]如果修改列表中列表[1,2]的值则会一起修改
- 深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)
知识点2:set集合
- 去重功能,集合本身无序、不重复,所以不能通过索引和键进行取值,集合对象是无序可哈希(不可改变)的值(也就是说对于set([[1,2],3,4])是不行的,因为列表里面中还包含了列表(可改变的值),所以会出现set失败)
- 空集合(set()),而{}是字典,集合分可变和不可变(frozenset),一般我们说的都是可变的,由于可变,所以set()本身就是不可哈希的,因此不能作为字典的key
- 创建集合:set("liu")就是{'l', 'i', 'u'}且类型为set,注意虽然是大括号但是不是字典类型
- 访问集合:由于集合本身的无序,所以不能使用索引、切片等访问,只能通过循环遍历访问或者in not in去判断是否是集合元素
- 集合添加元素:add方法和update,详情如下
s = set("liu")
s.add("ta") #添加一个元素'ta'
s.update("za") #添加两个元素,'z'和'a'
s.update(["",""]) #添加两个元素'34'和'12' print(s)
结果:
{'ta', 'l', 'u', 'a', '12', 'z', 'i', '34'}- 集合元素删除:remove(元素)删除指定元素,pop()随机删除集合元素,s.clear()清空集合元素,剩下一个空集合,del s(删除集合,删除后s就不存在了)
- 集合类型操作:
s1 = {"a", "b", "c"}
s2 = {"c", "d", "e"} # 交集
# 两个集合中的共有元素
print(s1 & s2) # {'c'}
print(s1.intersection(s2)) # {'c'} # 并集(联合)
print(s1 | s2) # {'e', 'd', 'b', 'a', 'c'}
print(s1.union(s2)) # {'e', 'd', 'b', 'a', 'c'} # 差集
print(s1 - s2) # {'a', 'b'}
print(s1.difference(s2)) # {'a', 'b'} # 反交集(对称差集)
print(s1 ^ s2) # 两个集合中单独存在的数据 {'e', 'a', 'd', 'b'}
print(s1.symmetric_difference(s2)) # 两个集合中单独存在的数据 {'e', 'a', 'd', 'b'} s1 = {"a", "b"}
s2 = {"a", "b", "c"} # 子集
print(s1 < s2) # set1是set2的子集吗? True
print(s1.issubset(s2))
# 超集(父级)
print(s1 > s2) # set1是set2的超集吗? False,s2是s1的超集
print(s1.issuperset(s2))
知识点3:函数
- 必需参数(以正确的顺序传入函数。调用时的数量必须和声明时的一样。类似f(name, age),传入的时候这样f("liu", 18))
- 关键字参数(使用关键字参数允许函数调用时参数的顺序与声明时不一致。类似f(name, age),传入的时候这样f(age=18, name="liu"))
- 缺省参数(调用函数时,缺省参数的值如果没有传入,则被认为是默认值。类似f(name, age = 18),传入的时候这样f(name="liu"),而age为默认参数)
- 不定长参数(加了星号(*)的变量名会存放所有未命名的变量参数。而加(**)的变量名会存放命名的变量参数,*args会将参数存成元祖,**kwargs会将参数存放成字典)
1、总结四种参数位置优先级:必需参数和关键字参数放最左边,缺省(默认参数)第二位,不定长参数放第三位(**args放在左边,**kwargs参数放在右边)
2、函数注意点:
- 函数内没有return,默认返回None
- 如果return多个对象,python会自动帮我们将多个对象封装成元祖返回
- test(*args)中* 的作用其实就是把序列 args 中的每个元素,当作位置参数传进去。比如上面这个代码,如果 args 等于 (1,2,3) ,那么这个代码就等价于 test(1, 2, 3)
- test(**kwargs)中** 的作用则是把字典 kwargs 变成关键字参数传递。比如上面这个代码,如果 kwargs 等于 {'a':1,'b':2,'c':3} ,那这个代码就等价于 test(a=1,b=2,c=3)
3、python中的作用域分4种情况:
- L:local,局部作用域,即函数中定义的变量;
- E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
- G:globa,全局变量,就是模块级别定义的变量;
- B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:局部作用域>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,而nonlocal关键字是修改嵌套作用域(enclosing作用域,外层非全局作用域)
4、函数小结:
(1)变量查找顺序:LEGB,局部作用域>外层作用域>当前模块中的全局>python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。
一个有趣的函数例子:
def outer():
def inner():
return 1
return inner #返回inner的内存地址
a = outer #将outer的内存地址赋值了给a
print(a()) #相当于outer(),结果实际上是返回了inner的内存地址
print(a()()) #这里打印了结果1,因为执行了inner,所以返回了1
5、函数的递归
定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
其实函数的递归最典型的就是斐波那契数列(1、1、2、3、5、8.。。),下面是这个的例子
u'''斐波那契数列(1、1、2、3、5、8.。。)'''
#第一种:循环方式实现
def feibo1(n):
if n <= 1:
return n
first_num = 0
second_num = 1
for i in range(n-1):
sum1 = first_num + second_num
first_num = second_num
second_num = sum1
return sum1 #第二种:递归方式实现
def feibo2(n):
if n <= 1:
return n
return feibo2(n-1) + feibo2(n-2)
递归函数的优点: 是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)
6、重要的内置函数:
1 filter(function, sequence) 对sequence中的item依次执行function(item),将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。
list1 = [1, 2, 3, 4] def fun(str1):
if str1 != 3:
return str1 result = filter(fun, list1) #主要是过滤作用,返回结果为True的值
print(list(result)) -->结果是[1, 2, 4]
2 map(function, sequence) 对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回,当然map也支持多个sequence,这就要求function也支持相应数量的参数输入。
list1 = ["a", "b", "c"] def fun1(str):
return str + "test" result1 = map(fun1, list1) #注意下面map和filter区别,如果没条件过滤,filter后还是返回本身
result2 = filter(fun1, list1)
print(list(result1)) #结果是['atest', 'btest', 'ctest']
print(list(result2)) #结果是['a', 'b', 'c']
def add1(x,y): #多个sequence的情况
return x+y
print (list(map(add1, range(10), range(10))))##[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
3 reduce(function, sequence, starting_value) 对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用.
from functools import reduce def fun1(x, y):
return x*y result = reduce(fun1, range(1, 6)) # 通过reduce就直接实现了阶乘,注意下,这里reduce的结果就是一个值而不是迭代器
print(result)
4 lambda 匿名函数
像上面reduce实现的阶乘,这里通过匿名函数再实现,对比下两者:
from functools import reduce
result = reduce(lambda x, y: x*y, range(1, 6)) #匿名函数的命名规则,用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(x,y) ,冒号(:)右侧表示函数的返回值(x*y)
print(result)
Python全栈开发记录_第四篇(集合、函数等知识点)的更多相关文章
- Python全栈开发记录_第三篇(linux(ubuntu)的操作)
该篇幅主要记录linux的操作,常见就不记录了,主要记录一些不太常用.难用或者自己忘记了的点. 看到https://www.cnblogs.com/resn/p/5800922.html这篇幅讲解的不 ...
- Python全栈开发记录_第十篇(反射及选课系统练习)
反射机制:反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块中寻找指定函数,对其进行操作.也就是利用字符串的形式去对象(模块)中操作(查找or获取or删除or添加)成员,一种基于字符串的事件 ...
- Python全栈开发记录_第八篇(模块收尾工作 json & pickle & shelve & xml)
由于上一篇篇幅较大,留下的这一点内容就想在这里说一下,顺便有个小练习给大家一起玩玩,首先来学习json 和 pickle. 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过, ...
- Python全栈开发记录_第七篇(模块_time_datetime_random_os_sys_hashlib_logging_configparser_re)
这一篇主要是学习python里面的模块,篇幅可能会比较长 模块的概念:在Python中,一个.py文件就称之为一个模块(Module). 模块一共三种: python标准库 第三方模块 应用程序自定义 ...
- Python全栈开发记录_第六篇(生成器和迭代器)
说生成器之前先说一个列表生成式:[x for x in range(10)] ->[0,1,2....,9]这里x可以为函数(因为对python而言就是一个对象而已),range(10)也可 ...
- Python全栈开发记录_第五篇(装饰器)
单独记录装饰器这个知识点是因为这个知识点是非常重要的,必须掌握的(代码大约150行). 了解装饰器之前要知道三个知识点 作用域,上一篇讲到过顺序是L->E->G->B 高阶函数: 满 ...
- Python全栈开发记录_第一篇(循环练习及杂碎的知识点)
Python全栈开发记录只为记录全栈开发学习过程中一些难和重要的知识点,还有问题及课后题目,以供自己和他人共同查看.(该篇代码行数大约:300行) 知识点1:优先级:not>and 短路原则:a ...
- Python全栈开发记录_第九篇(面向对象(类)的学习)
有点时间没更新博客了,今天就开始学习类了,今天主要是面向对象(类),我们知道面向对象的三大特性,那就是封装,继承和多态.内容参考该博客https://www.cnblogs.com/wupeiqi/p ...
- Python全栈开发记录_第二篇(文件操作及三级菜单栏增删改查)
python3文件读写操作(本篇代码大约100行) f = open(xxx.txt, "r", encoding="utf-8") 不写“r”(只读)默认是只 ...
随机推荐
- latex中使用定理、证明、缩进
1.定理和证明 \documentclass[a4paper,UTF8]{article} \usepackage{ctex} \usepackage{amsthm,amsmath,amsfonts, ...
- conts、var 、let的区别
1.const定义的变量不可以直接修改,通过 this.a = 'kkk' 进行修改, 而且必须初始化. 2.var定义的变量可以修改,如果不初始化会输出undefined 3.let是块级作用域,函 ...
- 同时兼容ie8 与ie11
最近公司发文规定说程序要必须同时兼容ie8与ie11 下面是在修改程序时遇到的一些问题. 1:new Date 获取年的问题,在ie8及以下ie以下版本是可以用getYear()方法来获取年得到的数值 ...
- PAT乙级考前总结(五)
字符串处理 1003 我要通过! (20 分) “答案正确”是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否 ...
- Spock - Document - 03 - Data Driven Testing
Data Driven Testing Peter Niederwieser, The Spock Framework TeamVersion 1.1 Oftentimes, it is useful ...
- 兄弟连学python---网络简介
网络简介 1.什么是网络 网络是辅助双方能够连接在一起的工具 使用网络的目的 为了联通多方然后进行通讯,能够让软件在不同的电脑上运行,相互传输数据 网络的发展 网络协议 什么是协议 约定俗成的,没有理 ...
- hdu 4506 快速幂
小明自从告别了ACM/ICPC之后,就开始潜心研究数学问题了,一则可以为接下来的考研做准备,再者可以借此机会帮助一些同学,尤其是漂亮的师妹.这不,班里唯一的女生又拿一道数学题来请教小明,小明当然很高兴 ...
- 构建之法 chapter1 心得
阅读完了<构建之法>第一章后,觉得我们平时使用的软件并不是自己想象中的那样简单,用的时候是觉得很方便,但从来没有考虑过一个软件的背后需要一个团队多少的付出才能换来一个获得用户频频好评的软件 ...
- MySql最土的语法解释使用一。
create database namedb charset utf8;解释:创建一个数据库 namedb改成你的数据库名字,charset是字符集的意思 utf8代表数据库支持中文字符集.必须分号结 ...
- Python练习四
1.任意输入一串文字加数字,统计出数字的个数,数字相连的视为一个,如:12fd2表示两个数字,即12为一个数字. content = input("请输入内容:") for i i ...