基本数据类型之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 + y
return z def main():
a = 12
b = 13
c = 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 formataddr msg = 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()

  局部变量和全局变量

  • 局部变量,从字面上的意思理解就是肯定是生活在某个局部地方的,好!那在这里,定义在函数体内的变量叫做局部变量
  • 全局变量,定义在函数体外的变量叫做全局变量
  • 局部变量只可被本函数使用,全局变量可以被所有的语句访问使用
  • 由于局部变量定义在函数体内,故多个函数可以在各自函数体内使用相同的变量名作为自己的变量

  看例子,我会找茬

def f1():
x = 12
print(x) def f2():
y = 13
print(y) def f3():
print(x)
print(y) def main():
f1()
f2()
f3() main()
print('End!')

  是不是发现了错误呢?这就是函数内部调用其他的函数里的局部变量的错误

  • 全局变量没有定义在任何函数体内,如果在某个函数里修改某个全局变量,必须用global声明一下这个变量是全局的才能修改
def printlocalx():
x = 12
print('f1 local x =',x) def printlocaly():
y = 13
print('f2 local y =',y) def readglobal():
print('f3 read global x =',x)
print('f3 read global y =',y) def modifyglobal():
global x
print('f4 write x = -1')
x = -1 def main():
printlocalx()
printlocaly()
readglobal()
modifyglobal() x = 200
y = 100
main()
print('after modified global x =',x)
print('End')
结果为:
f1 local x = 12
f2 local y = 13
f3 read global x = 200
f3 read global y = 100
f4 write x = -1
after modified global x = -1
End
  • 为了规范起见,全局变量建议用大写,局部变量用小写

  形参和实参

  • 在定义函数时的变量称作函数的形参,作为外部值传入函数的接口
  • 函数调用时的变量称作实参
def multi(x,y):    #定义时的x,y就是形参
z = x * y
return z def main():
a = 12
b = 13
c = 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'>

  你看程序能自动识别构造元素和字典,这样就可以实现给函数传入多个参数了

欢迎大家对我的博客内容提出质疑和提问!谢谢

                                                                             笔者:拍省先生   

python基础-第三篇-函数编程的更多相关文章

  1. Python基础第三篇

    一.collections系列 Counter是对字典类型的补充,用于追踪值的出现次数,具备字典的所有功能 + 自己的功能 1.计数器Counter import collections a='aba ...

  2. Python 基础语法(三)

    Python 基础语法(三) --------------------------------------------接 Python 基础语法(二)------------------------- ...

  3. NHibernate 映射基础(第三篇) 简单映射、联合主键

    NHibernate 映射基础(第三篇) 简单映射.联合主键 NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源. 一.简单映射 下面先来 ...

  4. Python基础知识(三)

    Python基础知识(三) 一丶整型 #二进制转成十进制的方法 # 128 64 32 16 8 4 2 1 1 1 1 1 1 1 例如数字5 : 101 #十进制转成二进制的方法 递归除取余数,从 ...

  5. Python基础学习三

    Python基础学习三 1.列表与元组 len()函数:可以获取列表的元素个数. append()函数:用于在列表的最后添加元素. sort()函数:用于排序元素 insert()函数:用于在指定位置 ...

  6. python数据挖掘第三篇-垃圾短信文本分类

    数据挖掘第三篇-文本分类 文本分类总体上包括8个步骤.数据探索分析->数据抽取->文本预处理->分词->去除停用词->文本向量化表示->分类器->模型评估.重 ...

  7. Python基础【第一篇】

     一.Python简介 Python的创始人(Guido von Rossum 荷兰人),Guido希望有一种语言既能像C一样方便地调用操作系统的功能接口,也能像shell脚本一样,轻松地实现编程,A ...

  8. Python 基础学习 总结篇

    Python 基础学习总结 先附上所有的章节: Python学习(一)安装.环境配置及IDE推荐 Python学习(二)Python 简介 Python学习(三)流程控制 Python学习(四)数据结 ...

  9. python基础-第六篇-6.2模块

    python之强大,就是因为它其提供的模块全面,模块的知识点不仅多,而且零散---一个字!错综复杂 没办法,二八原则抓重点咯!只要抓住那些以后常用开发的方法就可以了,哪些是常用的?往下看--找答案~ ...

随机推荐

  1. js数组最大值和最小值计算

    基本概念 reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值. reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被 ...

  2. 利用|,&amp;,^,~,&lt;&lt;,&gt;&gt;&gt;写出高效艺术的代码

    简单介绍: 大家在阅读源代码的时候常常会看到一些比方以下这样特别难理解的代码. cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (motionEve ...

  3. gcc 编译流程分析

    //test.c #include<stdio.h> int main() { ,y=; printf("x=%d y=%d\n",x,y); ; } 1:预处理阶段, ...

  4. 示例 - C#脚本代码采集搜狐NBA球员, 球队和比赛实况

    最近 @甜瓜 (QQ:1069629945) 开发了一套NBA数据采集脚本, 我觉得很赞. 经他允许发布出来和大家分享一些经验: 球员球队: http://data.sports.sohu.com/n ...

  5. 70个shell经常使用操作

    1) 怎样向脚本传递參数 ? ./script argument 样例: 显示文件名脚本 ./show.sh file1.txt cat show.sh #!/bin/bash echo $1 2) ...

  6. 大数据(10) - HBase的安装与使用

    HBaes介绍 HBase是什么? 数据库 非关系型数据库(Not-Only-SQL) NoSQL 强依赖于HDFS(基于HDFS) 按照BigTable论文思想开发而来 面向列来存储 可以用来存储: ...

  7. 关于Cocos2d-x中两个场景之间参数的传递

    两个场景之间,有的时候要进行参数传递,如果想通过实例化出一个场景,从而得到属性和方法是不对的想法 你有两个场景,第一场景是用户登录界面,第二场景则是你登录后的界面,你如何将用户登录的值传到第二个场景呢 ...

  8. 【BZOJ】1638: [Usaco2007 Mar]Cow Traffic 奶牛交通(dfs+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1638 一条边(u, v)经过的数量=度0到u的数量×v到n的数量 两次记忆化dfs算出他们即可 #i ...

  9. 基于docker部署的微服务架构(四): 配置中心

    原文:http://www.jianshu.com/p/b17d65934b58%20 前言 在微服务架构中,由于服务数量众多,如果使用传统的配置文件管理方式,配置文件分散在各个项目中,不易于集中管理 ...

  10. [转]VC++下使用ADO操作数据库

    (1).引入ADO类 1 2 3 #import "c:program filescommon filessystemadomsado15.dll" no_namespace re ...