python基础-第三篇-函数编程
基本数据类型之set
- set是无序不允许重复的集合
- set创建:s = set() 创建空集合 s = {11,22,33}
- 转换s = set(可迭代数据)
li = [11,22,33,44] s = set(li) print(s) #结果为{33, 11, 44, 22}
- 集合元素的添加与清空
se = {11,22,33} se.add(44) print(se) #结果为{33, 11, 44, 22} se.clear() print(se) #结果为set()
- set_name1.difference(set_name2) 找到name1中存在,name2不存在的元素组成新的集合
se = {11,22,33} be = {33,55} ret1 = se.difference(be) ret2 = be.difference(se) print(ret1) #结果为{11, 22} print(ret2) #结果为{55}
- set_name1.difference_update(set_name2) 找到name1中存在,name2不存在的元素组成的集合更新给自己
se = {11,22,33} be = {33,55} se.difference_update(be) print(se) #{11, 22}
- set_name1.isdisjoint(set_name2) name1和name2无交集返回Ture,有交集就返回False
se = {11,22,33} be = {33,55} ret = se.isdisjoint(be) print(ret) #结果为False
- set_name1.issubset(set_name2) name1是否为name2的子序列
- set_name1.issuperset(set_name2) name1是否为name2的父序列
s1 = {11,22,33,44,55} s2 = {11,22} ret = s2.issubset(s1) #s2是s1的子序列吗? print(ret) #结果为True ret1 = s1.issuperset(s2) #s1是s2的父序列吗? print(ret1) #结果为True
- set_name1.symmetric_difference(set_name2) 把两集合相同的元素剔除,用剩下的元素组成新的集合
- set_name1.symmetric_difference_update(set_name2) 把两集合相同的元素剔除,用剩下的元素组成的集合赋给name1
se = {11,22,33,44} be = {11,22,77,55} ret = se.symmetric_difference(be) print(ret) #结果为{33, 44, 77, 55} se.symmetric_difference_update(be) print(se) #结果为{33, 44, 77, 55}
- set_name.discard(元素项)和set_name.remove(元素项) 都是移除,不过remove移除不存在的元素会报错
se = {11,22,33,44} se.discard(44) print(se) #结果为{33, 11, 22} se.remove(22) print(se) #结果为{33, 11} se.discard(44) # se.remove(44) #报错
- set_name1.intersection(set_name2) 求两集合的交集
se = {11,22,33,44} be = {11,22,77,55} ret = se.intersection(be) print(ret) #结果为{11, 22}
- set_name1.union(set_name2) 求两集合的并集,为新的集合
se = {11,22,33,44} be = {11,22,77,55} ret = se.union(be) print(ret) #结果为{33, 11, 44, 77, 22, 55}
- set_name.pop() 不需要参数,随机删除一个
se = {11,22,33,44,4,4,5,1,5,2,8,4,9,6,5,65,2,5,2,58,2,58,2,8,52,8,6,654,487,4} for i in range(10):ret = se.pop()print(ret)print(se,type(se))
- set_name1.update(set_name2) 取并集并附给name1
se = {11,22,33,44} be = {11,22,77,55} se.update(be) print(se) #结果为{33, 11, 44, 77, 22, 55}
三元运算
- 格式:name = 值1 if 条件 else 值2
- 条件成立,就值1赋给name,否则把值2赋给name
- 可以这么说三元运算就是条件语句的简化版
name = 12 if 2>3 else 25 print(name) #结果为25 name = 12 if 1==1 else 25 print(name) #结果为12
不同数据类型在内存的存址方式
- str(字符串) 一次性创建,不能修改,如果要修改必须重新创建
- list(列表) 存址方式为链表形式,元素之间记住了上一个元素的位置,下一个元素的位置
深浅拷贝
- 对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址
import copy str1 = 'alex' str2 = str1 #赋值 str3 = copy.copy(str1) #浅拷贝 str4 = copy.deepcopy(str1) #深拷贝 print(id(str1),id(str2),id(str3),id(str4)) #结果为8373168 8373168 8373168 8373168
import copy num1 = 1234 num2 = num1 #赋值 num3 = copy.copy(num1) #浅拷贝 num4 = copy.deepcopy(num1) #深拷贝 print(id(num1),id(num2),id(num3),id(num4)) #结果为1331088 1331088 1331088 1331088
- 对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的
import copy dict1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} dict2 = dict1 #赋值 dict3 = copy.copy(dict1) dict4 = copy.deepcopy(dict1) print(id(dict1),id(dict2),id(dict3),id(dict4)) #结果为10077192 10077192 10505160 10464264
看到这结果,我们可以得出,赋值对于字典而言,其内存地址是没有发生变化的,但是对浅拷贝和深拷贝的话,其内存地址都改变了,你可能会想,浅拷贝和深拷贝有啥区别了?
- 浅拷贝只拷贝第一层,深拷贝除了最后一层不拷贝,其他的都拷贝
浅拷贝:
import copy dict1 = {"k1": "wu", "k2": 123, "k3": {'偶像':'景女神','人生格言':['景女神是最棒的','我们都是最棒的']}} dict2 = copy.copy(dict1) #浅拷贝 # dict2['k1'] = 'jingliyang' #在第一层,dict1没有跟着dict2变化 # print(dict1) #结果为{'k1': 'wu', 'k2': 123, 'k3': {'偶像': '景女神', '人生格言': ['景女神是最棒的', '我们都是最棒的']}} # print(dict2) #结果为{'k1': 'jingliyang', 'k2': 123, 'k3': {'偶像': '景女神', '人生格言': ['景女神是最棒的', '我们都是最棒的']}} dict2['k3']['人生格言'] = '每天很美好' #看到没,在第二层,dict1贱贱的跟着dict2变化了 print(dict1) #结果为{'k2': 123, 'k3': {'人生格言': '每天很美好', '偶像': '景女神'}, 'k1': 'wu'} print(dict2) #结果为{'k2': 123, 'k3': {'人生格言': '每天很美好', '偶像': '景女神'}, 'k1': 'wu'}
附图:
深拷贝:
import copy dict1 = {"k1": "wu", "k2": 123, "k3": {'偶像':'景女神','人生格言':['景女神是最棒的','我们都是最棒的']}} dict2 = copy.deepcopy(dict1) #深拷贝 # dict2['k1'] = '景丽洋' #在这里改变第一层,dict1没有跟着dict2变化 # print(dict1) #{'k3': {'人生格言': ['景女神是最棒的', '我们都是最棒的'], '偶像': '景女神'}, 'k1': 'wu', 'k2': 123} # print(dict2) #{'k1': '景丽洋', 'k3': {'人生格言': ['景女神是最棒的', '我们都是最棒的'], '偶像': '景女神'}, 'k2': 123} dict2['k3']['人生格言'] = '景女神,加油!' #你看,第二层dict1还是没有跟着dict2变化 print(dict1) #{'k3': {'偶像': '景女神', '人生格言': ['景女神是最棒的', '我们都是最棒的']}, 'k1': 'wu', 'k2': 123} print(dict2) #{'k3': {'偶像': '景女神', '人生格言': '景女神,加油!'}, 'k1': 'wu', 'k2': 123}
附图:
函数
- 函数是面向过程编程,也叫函数式编程
- 当程序运行时,解释器从上往下解释,遇定义函数时先读取到内存,但不执行
- 执行 --函数名()
- 语法结构:
def function_name(args):功能块return 返回值
- return后面是返回值,不写return,默认返回None,返回值是可以用变量接收的
- 在函数中,执行了return,函数后面的代码就不执行了
为了理解更透彻,让我们先看一个例子:
def add(x,y):z = x + yreturn zdef main():a = 12b = 13c = add(a,b)print(c)main() print('End!')
首先这个例子中定义两个函数,分别为add和main两个函数,add函数有两个形式参数x和y,而main函数无形参也无返回值,在执行main函数的过程中又去调用了add函数
发送邮件实例
复制代码import smtplib from email.mime.text import MIMEText from email.utils import formataddrmsg = MIMEText('邮件内容', 'plain', 'utf-8') msg['From'] = formataddr(["武沛齐",'wptawy@126.com']) msg['To'] = formataddr(["走人",'424662508@qq.com']) msg['Subject'] = "主题"server = smtplib.SMTP("smtp.126.com", 25) server.login("wptawy@126.com", "邮箱密码") server.sendmail('wptawy@126.com', ['424662508@qq.com',], msg.as_string()) server.quit()
View Code
局部变量和全局变量
- 局部变量,从字面上的意思理解就是肯定是生活在某个局部地方的,好!那在这里,定义在函数体内的变量叫做局部变量
- 全局变量,定义在函数体外的变量叫做全局变量
- 局部变量只可被本函数使用,全局变量可以被所有的语句访问使用
- 由于局部变量定义在函数体内,故多个函数可以在各自函数体内使用相同的变量名作为自己的变量
看例子,我会找茬
def f1():x = 12print(x)def f2():y = 13print(y)def f3():print(x)print(y)def main():f1()f2()f3()main() print('End!')
是不是发现了错误呢?这就是函数内部调用其他的函数里的局部变量的错误
- 全局变量没有定义在任何函数体内,如果在某个函数里修改某个全局变量,必须用global声明一下这个变量是全局的才能修改
def printlocalx():x = 12print('f1 local x =',x)def printlocaly():y = 13print('f2 local y =',y)def readglobal():print('f3 read global x =',x)print('f3 read global y =',y)def modifyglobal():global xprint('f4 write x = -1')x = -1def main():printlocalx()printlocaly()readglobal()modifyglobal()x = 200 y = 100 main() print('after modified global x =',x) print('End')
结果为:f1 local x = 12f2 local y = 13f3 read global x = 200f3 read global y = 100f4 write x = -1after modified global x = -1End
- 为了规范起见,全局变量建议用大写,局部变量用小写
形参和实参
- 在定义函数时的变量称作函数的形参,作为外部值传入函数的接口
- 函数调用时的变量称作实参
def multi(x,y): #定义时的x,y就是形参z = x * yreturn zdef main():a = 12b = 13c = multi(a,b) #调用时的a,b就是实参print(c) main() print('End')
位置参数和关键词参数
- 按照函数定义时的位置顺序传入值的方式称作位置参数传入
- 按照函数定义时的关键词对应关系传入值的方式称作关键词参数传入,这个也是老师说的指定参数
#梯形面积公式 def trapezoid_area(base_up,base_down,height):return 1/2*(base_up+base_down)*height print(trapezoid_area(1,2,3)) #这种传入参数的方式被称作位置参数传入 result = trapezoid_area(base_up=1,base_down=2,height=3) #这种传入参数的方式称为关键词参数传入 print(result)
默认参数
- 默认参数就是在函数定义时给某个参数设定默认值,默认参数必须在普通参数之后
- 默认参数在不给其传值时,使用默认值,给值就是修改默认值
def trapezoid_area(base_up,base_down,height=3):return 1/2*(base_up+base_down)*height result1 = trapezoid_area(1,2) #传入两个参数也可,也可修改三参,即默认参数 print(result1)
你不知道的小秘密,你常用的print居然是一个既熟悉又陌生的人儿
print(' *',' ***',' *****',' |',sep='\n')
sep为print函数的默认参数,默认值为空格,传入的\n为换行
动态参数
- def func(*args) 接受多个参数,内部自动构造元组
def f1(*a):print(a,type(a))f1(123) #结果为(123,) <class 'tuple'>#多传几个 f1(11,22,33) #结果为(11, 22, 33) <class 'tuple'>
你看,在定义函数的时候给参数前加了*,然后调用函数时输出的结果为元组,那如果传了列表呢?
def f1(*a):print(a,type(a))li = [11,22,33] f1(li) #结果为([11, 22, 33],) <class 'tuple'>
结果是把列表当整体作为元素的元素了,那如果我们就是想要把列表的每个元素作为构造元组的元素呢?
def f1(*a):print(a,type(a))li = [11,22,33] f1(*li) #结果为(11, 22, 33) <class 'tuple'>
其实只要在执行函数时传入的参数前加*就可以了
- def func(**kwargs) 接收多个参数,内部自动构造字典
def f2(**b):print(b,type(b))f2(a1 = 123) #结果为{'a1': 123} <class 'dict'>
好,如果要给其传入字典,而且也是要把每个键值对用于构造的字典的键值对,应该怎么做呢?相信很多人都想到了在前面加**吧?
def f2(**b):print(b,type(b))dict1 = {'k1':'景女神','k2':'景女神是最棒的'} f2(**dict1) #结果为{'k2': '景女神是最棒的', 'k1': '景女神'} <class 'dict'>
另外,告诉你,如果传入字典,你不加**,是会报错的
- def func(*args,**kwargs):接受多个参数,既可以自动构造元组,又可以自动构造字典,而且一个*的必须在两个*的前面
def f3(*args,**kwargs):print(args,type(args))print(kwargs,type(kwargs))f3(11,22,33,k1=123,k2=456) 结果为:(11, 22, 33) <class 'tuple'>{'k1': 123, 'k2': 456} <class 'dict'>
你看程序能自动识别构造元素和字典,这样就可以实现给函数传入多个参数了
欢迎大家对我的博客内容提出质疑和提问!谢谢
笔者:拍省先生
转载于:https://www.cnblogs.com/xinsiwei18/p/5517936.html
python基础-第三篇-函数编程相关推荐
- Python基础语法入门篇(一)
Python基础语法入门篇(二) 1. 注释 在我们工作编码的过程中,如果一段代码的逻辑比较复杂,不是特别容易理解,可以适当的添加注释,以辅助自己 或者其他编码人员解读代码. 注释是给程序员看的,为了 ...
- Python:第三篇【Python】实用库与框架-关东升-专题视频课程
Python:第三篇[Python]实用库与框架-612人已学习 课程介绍 本课程包括6章.内容包括Python数据交换格式,Python数据库编程,Python网络编程,wxPyth ...
- Python基础(三)--序列
Python基础(三)--序列 1 序列相关的概念 1.1 什么是序列 序列是一种可迭代对象,可以存储多个数据,并提供数据的访问. 序列中的数据称为元素,Python内置的序列类型有:列表(list) ...
- JavaScrip 基础 第三篇
JavaScrip 基础 第三篇 JS分支结构 流程控制 在一个程序执行的过程中 ,各条代码执行顺序对程序结果是有直接影响的,很多时候需要通过控制代码 执行顺序来实现完成的功能 简单理解:流程控制就是 ...
- Python基础第三课-基本数据类型
Python基础第三课-基本数据类型 1.几个基本概念 1.1 表达式 1.2 语句 1.3 程序(program) 1.4 函数(function) 2.标识符 2.1 关键字 2.2 标识符概念 ...
- python基础-第六篇-6.2模块
python之强大,就是因为它其提供的模块全面,模块的知识点不仅多,而且零散---一个字!错综复杂 没办法,二八原则抓重点咯!只要抓住那些以后常用开发的方法就可以了,哪些是常用的?往下看--找答案~ ...
- python:python基础语法三,列表、元组、字典、集合
python基础语法 文章目录 python基础语法 列表(list) 列表简介 切片 列表修改元素 列表的方法 遍历列表 序列(sequence) 序列的基本操作 range()函数 EMS(Emp ...
- python 基础第六篇
回顾上周所有内容 python基础 Python是一门解释型. 弱类型语言 print("内容", "内容", end="\n") 打印语句 ...
- Python新手引导 第三篇-Python基础和字符编码
阅读本文需要4.66分钟 <!--more--> 有其他计算机语言基础的同学,阅读本篇基础部分建议1到2分钟. 基础类型.变量和字符编码 list 和 tuple 第一.基础类型.变量和字 ...
最新文章
- nginx访问日志,错误日志参数说明
- Serverless 实战 —— Funcraft OSS ROS 进行 CI/CD
- CG CTF MISC 图种
- LVS负载均衡群集部署之——NAT模式的介绍及搭建步骤
- JVM从入门到精通(四):内存屏障与JVM指令,对象的内存布局
- 山西万荣盛装迎新春 首届群众文化艺术节启幕
- mysql基础和高级整理_mysql基础整理01
- RedHat系列软件管理(第二版) --源码包安装
- win10 安装 mysql-8.0.12
- uni-app的列表搜索框_微信怎么搜索小程序?小程序能有什么用?
- java email 正则 验证
- Spark学习之路 (十七)Spark分区
- python 公众号开发框架_基于werobot框架的微信公众号开发
- TypeScript(四)声明文件、全局变量(三斜线指令)、npm包、UMD库、发布声明文件
- macbook macOS苹果电脑到底需不需要清理系统垃圾?
- Linux 常见问题
- Java虚拟机——Parallel Scavenge收集器
- Nginx配置文件目录实现pdf文件预览及下载
- DSPE-PEG7-NHS ester分子式:C63H1117N2O20P琥珀酰亚胺PEG连接剂
- STC15F2K60S2实现A/D转换
热门文章
- java代码实现解压文件_Java压缩/解压文件的实现代码
- 算法设计与分析_算法设计与分析(第2版)第2章分治策略回顾
- 佳能2900打印机与win10不兼容_佳能RF 1.4、RF 2增倍镜与RF 100500mm L IS USM并不完全兼容...
- 阿尔法贝塔阀原理_图总结 - 阿尔法个贝塔 - 博客园
- 汇编语言中变量的声明
- 【DSP复习主要知识点】(大概)
- 如何利用FFT(基2时间以及基2频率)信号流图求序列的DFT
- 八、非规则组织分析及其数学模型——平纹变化组织
- php 载入css就可以显示,如何在进度条加载后显示页面
- C和混编混合编程----strcpy缓存溢出原理