Python(一)—— 初识&基础数据类型

1. Python的介绍

1.1 Python的应用

1.1.1 目前Python主要应用领域

  • 云计算:云计算最火的语言, 典型应用OpenStack

  • WEB开发:众多优秀的WEB框架,典型WEB框架有Django;众多大型网站均为Python开发,Youtube、Dropbox、豆瓣等

  • 科学运算、人工智能:典型库NumPy、SciPy、Matplotlib、Enthought librarys、Pandas

  • 系统运维:运维人员必备语言

  • 金融:量化交易,金融分析,在金融工程领域,Python不但在用,且用的最多,而且重要性逐年提高。原因:作为动态语言的Python,语言结构清晰简单,库丰富,成熟稳定,科学计算和统计分析都很牛逼,生产效率远远高于C、C++、Java,尤其擅长策略回测

  • 图形GUI:PyQT、WxPython、TkInter

1.1.2 Python在一些公司的应用

  • 谷歌:Google App Engine 、code.google.com 、Google earth 、谷歌爬虫、Google广告等项目都在大量使用Python开发

  • CIA:美国中情局网站就是用Python开发的

  • NASA:美国航天局(NASA)大量使用Python进行数据分析和运算

  • YouTube:世界上最大的视频网站YouTube就是用Python开发的

  • Dropbox:美国最大的在线云存储网站,全部用Python实现,每天网站处理10亿个文件的上传和下载

  • Instagram:美国最大的图片分享社交网站,每天超过3千万张照片被分享,全部用Python开发

  • Facebook:大量的基础库均通过Python实现的

  • Redhat:世界上最流行的Linux发行版本中的yum包管理工具就是用Python开发的

  • 豆瓣:公司几乎所有的业务均是通过Python开发的

  • 知乎:国内最大的问答社区,通过Python开发(国外Quora)

  • 春雨医生:国内知名的在线医疗网站是用Python开发的

  • 除上面之外,还有搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝 、土豆、新浪、果壳等公司都在使用Python完成各种各样的任务

1.2. Python前言

1.2.1 编程语言

1.2.1.1 解释器
  • 计算机不能直接理解任何除机器语言以外的语言,必须要把程序语言翻译成机器语言,计算机才能执行程序

  • 编译器:将其他语言翻译成机器语言的工具

  • 编译器翻译的方式:编译,解释

  • 两种方式的区别在于翻译时间点的不同。当编译器以解释方式运行的时候,也称之为解释器

1.2.1.2 翻译方式
1.2.1.2.1 编译型与解释型
  • 编译型语言:程序执行之前需要有一个专门的编译过程,把程序编译成为机器语言的文件,运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依赖编译器,跨平台性差些

  • 解释型语言:解释型语言编写的程序不进行预先编译,以文本方式存储程序代码,会将代码一句一句直接运行。在发布程序时,看起来省了道编译工序,但是在运行程序的时候,必须先解释再运行

1.2.1.2.2 编译型与解释型对比
  • 编译型

    • 优点:编译器一般会有预编译的过程对代码进行优化。因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高。可以脱离语言环境独立运行

    • 缺点:编译之后如果需要修改就需要整个模块重新编译。编译的时候根据对应的运行环境生成机器码,不同的操作系统之间移植就会有问题,需要根据运行的操作系统环境编译不同的可执行文件

  • 解释型

    • 优点:有良好的平台兼容性,在任何环境中都可以运行,前提是安装了解释器(虚拟机)。灵活,修改代码的时候直接修改就可以,可以快速部署,不用停机维护

    • 缺点:每次运行的时候都要解释一遍,性能上不如编译型语言

  • 总结

    • 速度: 编译型比解释型快

    • 跨平台性: 解释型比编译型好

1.2.1.2.3 动态语言和静态语言
  • 通常我们所说的动态语言、静态语言是指动态类型语言和静态类型语言

  • 动态语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是一种典型的动态类型语言,其他的各种脚本语言如VBScript也多少属于动态类型语言

  • 静态语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译期间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表,其他的静态类型语言还有C#、JAVA等

1.2.1.2.4 强类型定义语言和弱类型定义语言
  • 强类型定义语言:强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。

  • 弱类型定义语言:数据类型可以被忽略的语言。它与强类型定义语言相反,一个变量可以赋不同数据类型的值

  • 强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。另外,“这门语言是不是动态语言”与“这门语言是否类型安全”之间是完全没有联系的!

  • 例如:Python是动态语言,是强类型定义语言(类型安全的语言); VBScript是动态语言,是弱类型定义语言(类型不安全的语言); JAVA是静态语言,是强类型定义语言(类型安全的语言)

  • 通过上面这些介绍,我们可以得出,Python是一门动态解释性的强类型定义语言

1.2.1.3 代表语言
  • 编译型:C、C++、GO、Swift、Object-C、Pascal

  • 解释型:JavaScript、Python、Ruby、PHP、Perl、Erlang

  • 混合型:Java、C#

1.2.2 认识Python

1.2.2.1 Python的优缺点

1、优点:

① Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序

② 开发效率非常高,Python有非常强大的第三方库,基本上你想通过计算机实现任何功能,Python官方库里都有相应的模块进行支持,直接下载调用后,在基础库的基础上再进行开发,大大降低开发周期,避免重复造轮子

③ 高级语言:当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节

④ 可移植性:由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工 作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就几乎可以在市场上所有的系统平台上运行

⑤ 可扩展性:如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们

⑥ 可嵌入性:你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能

2、缺点:

① 速度慢,Python 的运行速度相比C语言确实慢很多,跟JAVA相比也要慢一些,因此这也是很多所谓的大牛不屑于使用Python的主要原因,但其实这里所指的运行速度慢在大多数情况下用户是无法直接感知到的,必须借助测试工具才能体现出来,比如你用C运一个程序花了0.01s,用Python是0.1s,这样C语言直接比Python快了10倍,算是非常夸张了,但是你是无法直接通过肉眼感知的,因为一个正常人所能感知的时间最小单位是0.15-0.4s左右。其实在大多数情况下Python已经完全可以满足你对程序速度的要求,除非你要写对速度要求极高的搜索引擎等,这种情况下,当然还是建议你用C去实现的

② 代码不能加密,因为PYTHON是解释性语言,它的源码都是以名文形式存放的,不过我不认为这算是一个缺点,如果你的项目要求源代码必须是加密的,那你一开始就不应该用Python来去实现

③ 线程不能利用多CPU问题,这是Python被人诟病最多的一个缺点,GIL即全局解释器锁(Global Interpreter Lock),是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行,Python的线程是操作系统的原生线程。在Linux上为Pthread,在Windows上为Win thread,完全由操作系统调度线程的执行。一个Python解释器进程内有一条主线程,以及多条用户程序的执行线程。即使在多核CPU平台上,由于GIL的存在,所以禁止多线程的并行执行

④ 当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。由于整个Python语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都可以编写Python解释器来执行Python代码(当然难度很大)

1.2.2.2 Python的种类

1、CPython

  • 当我们从Python官方网站下载并安装好Python 3.6后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行Python就是启动CPython解释器

  • CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行

2、IPython

  • IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。好比很多国产浏览器虽然外观不同,但内核其实都是调用了IE

  • CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。

3、PyPy

  • PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度

  • 绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点

4、Jython

  • Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行

  • IronPython

    • IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码

小结:Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性

1.2.2.3 Python的特点

1、完全面向对象的语言
① 函数、模块、数字、字符串都是对象,Python中一切皆对象
② 完全支持继承、重载、多重继承
③ 支持重载运算符,也支持泛型设计

2、拥有一个强大的标准库
Python标准库提供了 系统管理、网络通信、文本处理、数据库接口、图形系统、XML 处理 等额外的功能

3、有大量的第三方模块
使用方式与标准库类似。它们的功能覆盖科学计算、人工智能、机器学习、Web 开发、数据库接口、图形系统 多个领域

4、面向对象的思维方式
① 面向对象是一种思维方式,也是一门程序设计技术
② 要解决一个问题前,首先考虑由谁来做,怎么做事情是谁的职责,最后把事情做好就行,这个对象就是“谁”
③ 要解决复杂的问题,就可以找多个不同的对象,各司其职,共同实现,最终完成需求
④ 先找一个可以完成功能的对象,并且使用对象所提供的能力来解决问题

1.2.2.4 交互式运行Python程序

1、直接在终端中运行解释器,而不输入要执行的文件名

2、在Python的Shell中直接输入Python的代码,会立即看到程序执行结果

3、交互式运行 Python 的优缺点

(1)优点:
适合于学习/验证 Python 语法或者局部代码

(2)缺点
① 代码不能保存
② 不适合运行太大的程序

4、退出 官方的解释器

① 直接输入 exit()

exit()

② 按热键 ctrl + d 可以退出解释器

2. 注释

  • 当行注释:# 被注释内容

  • 多行注释:'''被注释内容''',或者"""被注释内容"""

# 注释前
a = 1
b = 2

# 1.第一种注释后,按住Ctrl键和?键
# a = 1
# b = 2

# 2.第二种注释后,选择三个单引号或三个双引号
'''
a = 1
b = 2
'''

"""
a = 1
b = 2
"""

3. 基础数据类型

常量即指不变的量,如pai=3.141592653...,或在程序运行过程中不会改变的量。在Python中没有一个专门的语法代表常量,程序员约定俗成用变量名全部大写代表常量,我们主要看下面这些数字类型

3.1 变量

每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建

变量名 = 值   # 变量:先定义,后使用
  • 变量:把程序运行的中间结果临时的存在内存里,以便后续的代码调用

  • 变量的作用:昵称,其代指内存里某个地址中保存的内容

3.1.1 变量定义的规则

  • 变量名只能是字母、数字或下划线的任意组合

  • 变量名的第一个字符不能是数字

  • 以下关键字不能声明为变量名:['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']

  • 变量的定义要具有可描述性

3.1.2 变量定义的推荐方式

# 驼峰体(每个单词的首字母大写或者小写)

AgeOfLiu = 18    # 首字母大写  大驼峰体

aGEoFlIU = 18   # 首字母小写  小驼峰体


# 下划线(每个单词用下划线连接) -- 特别推荐

age_of_liu = 18

3.1.3 变量的输入

  • 所谓输入,就是用代码获取用户通过键盘输入的信息

  • 在Python中,使用 input 函数

  • 在 Python 中可以使用 input 函数从键盘等待用户的输入

  • 用户输入的 任何内容 Python 都认为是一个 字符串

  • 语法如下:

字符串变量 = input("提示信息:")

# 此时你的输入内容就被赋值给前面的 “字符串变量”

3.1.4 变量的格式化输出

1. % 被称为格式化操作符,专门用于处理字符串中的格式

  • 包含 % 的字符串,被称为格式化字符串

  • % 和不同的字符连用,不同类型的数据 需要使用不同的格式化字符

2. 语法格式如下:

print("格式化字符串" % 变量1)
print("格式化字符串" % (变量1, 变量2...))

3. 练习:问用户的姓名、年龄、工作、爱好 ,然后打印成以下格式

--------- info of 庆言  ---------
Name   : 庆言
Age      : 18
job        : Teacher
Hobbie : eat
------------- end -------------

只需要把要打印的格式先准备好, 由于里面的一些信息是需要用户输入的,你没办法预先知道,因此可以先放置个占位符,再把字符串里的占位符与外部的变量做个映射关系就好啦(类似于用书先把座位占好,然后同学再过来对应座位坐下)

① 代码展示:

# 1. 先把基本格式给填写好,需要用户输入的信息
name = input("Name:")
age = input("Age:")
job = input("Job:")
hobbie = input("Hobbie:")

此处的info信息里,不确定的先占位,等待后续输入
info = '''
--------- info of %s ---------    # 每行%s就是一个占位符,本行的代表后面扩号里的name 
Name  : %s                        # 此处的%s 代表 name 
Age   : %s                        # 此处的%s 代表 age  
Job   : %s                        # 此处的%s 代表 job 
Hobbie: %s                        # 此处的%s 代表 hobbie 
------------ end ------------
'''      

print(info %(name,name,age,job,hobbie))  # %号就是把前面的字符串与扩号的变量关联起来

② 代码展示:

③ 结果展示:

input接收的所有输入默认都是字符串格式!要想接收数字类型怎么办呢?可以把str转成int。

相反,能不能把字符串转成数字呢?必然可以,str(YourString)

① 代码如下:

# 假设用户输入的是18
age1 = input("Age1:")

# 打印一下年龄,以及该字段的类型  type()
print(age1,type(age1))

# 将输入内容用int()改变一下,看能否变成数值型
age2 = int(input("Age2:"))
# 再打印一下年龄,以及该字段的类型
print(age2,type(age2))

# 将输入内容用float()改变一下,看能否变成浮点型
age3 = float(input("Age3:"))
# 再打印一下年龄,以及该字段的类型
print(age3,type(age3))

② 输出结果:

现在有个问题,有这么个代码:

msg = "我是%s,年龄%d,目前学习进度为80%"
print(msg %('雨落',18))

'''
这样会报错的,因为在格式化输出里,你出现%默认为就是占位符的%,
但是我想在上面一条语句中最后的80%就是表示80%而不是占位符,怎么办?
'''

修改后的代码如下:

msg = "我是%s,年龄%d,目前学习进度为80%%" 
print(msg %('雨落',18))

'''
这样就可以了,第一个%是对第二个%的转译,
告诉Python解释器这只是一个单纯的%,而不是占位符
'''

3.2 数据类型

  • Python中常用的数据类型有多种,如下:

整数(int)   浮点数(float)  字符串(str)  布尔值(bool),
列表(list)  元组(tuple)    字典(dict)   集合(set)

int    数字:  主要用于运算。1,2,3...
float  小数:  主要用于计算。1.1,2.2...
str    字符串:简单少量的储存数据,并进行相应的操作。name = '雨落'
bool   布尔值:判断真假:True,False
tuple  元祖:  只读,不能更改。(1,'雨落')
list   列表:  大量有序数据 [1,'ses',True,[1,2,3],{'name':'雨落'}]
dict   字典:  大量数据,且是关联性比较强的数据 {'name':'雨落','age':22}

3.2.1 数字类型(int/float)

  • int(整型)

    • 在32位机器上,整数的位数为32位,取值范围为-2^31~2^31-1

    • 在64位系统上,整数的位数为64位,取值范围为-2^63~2^63-1

  • float(浮点型)

3.2.1.1 十进制与二进制转换

1. 十进制整数转换二进制整数

  • 十进制整数转换为二进制整数:采用 "除2取余,逆序排列" 法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商<=1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来

  • 例如:十进制的整数100(10)转化为二进制数为:1100100(2)

除以 2余数位次
(100) / 25000
(50) / 22501
(25) / 21212
(12) / 2603
(6) / 2304
(3) / 2115
(1) / 2016

2. 十进制小数转换二进制小数

  • 十进制小数转换成二进制小数:采用 "乘2取整,顺序排列" 法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止

  • 例如:十进制的小数0.8125(10)转化为二进制小数为:0.1101(2)

乘以2取整位次
0.8125 * 21.625010
0.6250 * 21.250011
0.2500 * 20.500003
0.5000 * 21.000014

3. 二进制转换十进制

  • 整数部要从右到左用二进制的每个数去乘以2的相应次方(从2的0次方开始);小数部则是从左往右开始(从2的-1次方开始)。最终得到的两个结果相加

  • 例如:二进制的1101.01(2)转化为十进制结果为13.25:

        整数部:1 * 2^0 + 0 * 2^1 + 1 * 2^2 + 1 * 2^3 = 1 + 0 + 4 + 8 = 13

        小数部:0 * 2^-1 + 1 * 2^-2 = 0.25

3.1.1.2 int的其他方法

bit_length() 快速的计算整数在内存中占用的二进制码的长度

num = 10                 # 转化成二进制就是1010               
print(num.bit_length())  # 当十进制用二进制表示时,最少使用的位数

# 运行结果:
4

3.2.2 字符串类型(str)

3.2.2.1 字符串的定义

字符串 就是 一串字符,是编程语言中表示文本的数据类型

1. 在 Python 中可以使用 一对双引号"或者 一对单引号'定义一个字符串

  • 虽然可以使用 \" 或者 \'做字符串的转义,但在实际开发中:

  • 如果字符串内部需要使用",可以使用'定义字符串

  • 如果字符串内部需要使用',可以使用"定义字符串

s1 = '这是字符串"str"'                        # 单引号内 用双引号引出
s2 = "这是字符串'str'"                        # 双引号内 用单引号引出
msg = "My name is YuLuo , I'm 22 years old!" # 单双引号配合使用

在Python中,加了引号的字符都被认为是字符串

name = "YuLuo"     # 双引号
age1 = "22"        # 只要加引号就是字符串
age2 = '22'        # 单引号也可以
age3 = 22          # int

# 3个引号也可以
msg1 = '''My name is qingyan, I am 18 years old!''' 

# 如果遇到多行的字符串,就得使用多引号
msg2 = '''
庆言是个女孩子,
庆言是个漂亮的女孩子,
庆言是个漂亮且大方的女孩子。
'''

2. 可以使用 索引 获取一个字符串中 指定位置的字符,索引计数从 0 开始

s = 'Python'  # P到n的索引依次是从0-5

3. 也可以使用 for循环遍历字符串中每一个字符

string = "Python"

for c in string:
    print(c)

# 输出结果:
P
y
t
h
o
n

3.2.2.2 字符串的基本操作

1. 字符串的拼接

数字可以进行加减乘除等运算,字符串也能,但只能进行"相加"和"相乘"运算,但是字符串的拼接只能是双方都是字符串,不能跟数字或其它类型拼接

name = 'YuLuo'      
age = '22'           # 此处的'22'是引号引起来的,所以是字符串

print(name + age)    # 相加其实就是简单拼接
# 输出结果:
YuLuo22

print(name * 10)     #相乘其实就是复制自己多少次,再拼接在一起
# 输出结果:
YuLuoYuLuoYuLuoYuLuoYuLuoYuLuoYuLuoYuLuoYuLuoYuLuo

2. 从字符串中取出单个字符 - 索引,语法为:'字符串'[索引]

组成字符串的字符从左至右,依次排列,索引即下标,依次为 :0,1,2,3....

print('string'[3])   # 'string'中索引为3的字符

# 输出结果:
i

3. 字符串的切片,语法为:'字符串'[头部索引:尾部索引:步长]

切片就是通过索引截取字符串的一段,形成新的字符串,顾头不顾尾

a = 'ABCDEFGHIJK'   # 先写出一个字符串用于以下操作

print(a[0:3])       # print(a[:3]) 从开头开始取0可以默认不写
# 输出结果:ABC

print(a[2:5])       # 索引为2的'C'拿到,但索引为5的'F'拿不到
# 输出结果:CDE

print(a[:])         # 默认到最后,即全部拿完
# 输出结果:ABCDEFGHIJK

print(a[:-1])       # -1是列表中最后一个元素的索引,但顾头不顾尾取不到K
# 输出结果:ABCDEFGHIJ

print(a[:5:2])      # 加步长,步长为2
# 输出结果:ACE

print(a[-1:-5:-2])  # 反向加步长,即从'KJIHGFEDCBA'中取
# 输出结果:KI

4. 获取字符串的长度 - len(),语法为:len('字符串')

print(len('string'))  # 'string'这个字符串的长度

# 输出结果:
6

5. 获取字符在字符串中出现的次数 - count(),语法为:'字符串'.count('字符串')

print('string'.count('s') )  # 's'在'string'中出现的次数

# 输出结果:
1

  count也可以切片中使用

a1 = 'abfajka012041'

ret1 = a1.count("a",0,4)    # 可切片,表示在'abfa'获取'a'的次数
print(ret1)

# 输出结果:
2

6. 获取字符在字符串中第一次出现的索引位置 - index,语法为:'字符串'.index('字符串')

print('string'.index('i'))  # 'i'在'string'中第一次出现的索引位置

# 输出结果:
3

3.2.2.3 字符串的操作 - 判断类型
代码说明
s.isspace()只包含空格,则返回 True
s.isalnum()至少有一个字符并且所有字符都是字母或数字则返回 True
s.isalpha()至少有一个字符并且所有字符都是字母则返回 True
s.isdecimal()只包含数字则返回 True,全角数字
s.isdigit()只包含数字则返回 True,全角数字、⑴、\u00b2
s.isnumeric()只包含数字则返回 True,全角数字,汉字数字
s.istitle()是标题化的(每个单词的首字母大写)则返回 True
s.islower()包含至少一个区分大小写的字符,并且所有这些字符都是小写,则返回 True
s.isupper()包含至少一个区分大小写的字符,并且所有这些字符都是大写,则返回 True
name='yuluo123'

print(name.isspace())    # False  字符串中不纯是空格组成
print(name.isalnum())    # True   字符串由字母或数字组成
print(name.isalpha())    # False  字符串不只由字母组成
print(name.isdecimal())  # False  字符串不只由十进制数组成
# replace 替换

name='yuluo say:I have one tesla, my name is yuluo.'
print(name.replace('yuluo','qingyan',1))  # 找到这句话的yuluo,并用qingyan替换一次

# 输出结果:
qingyan say: I have one tesla, my name is yuluo.

3.2.2.4 字符串的操作 - 查找和替换
代码说明
s.startswith(str)检查字符串是否是以 str 开头,是则返回 True
s.endswith(str)检查字符串是否是以 str 结束,是则返回 True
s.find(str, start=, end=)检测 str 是否包含在 string 中,如果 start 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回 -1
s.rfind(str, start=, end=)类似于 find(),不过是从右边开始查找
s.index(str, start=, end=)跟 find() 方法类似,不过如果 str 不在 string 会报错
s.rindex(str, start=, end=)类似于 index(),不过是从右边开始
s.replace(old_str, new_str, num)把 string 中的 old_str 替换成 new_str,如果 num 指定,则替换不超过 num 次
a2 = "dkfjdkfasf54"

ret2 = a2.endswith('jdk',3,6)     # 判断a2索引3-6的切片是否以jdk结尾的
print(ret2)                       # 输出结果:True

ret3 = a2.startswith("kfj",1,4)   # 判断a2索引1-4的切片是以kfj开头的
print(ret3)                       # 输出结果:True
# 寻找字符串中的元素是否存在

a = "dkfjdkfasf54"
ret6 = a.find("fjdk",1,6)   # 返回的找到的元素的索引,如果找不到返回-1
print(ret6)                 # 输出结果:2
# 寻找字符串中的元素索引

a = "dkfjdkfasf54"
ret61 = a.index("fjdk",4,6)    # 返回的找到的元素的索引,找不到报错
# print(ret61)                 # 输出结果:报错

3.2.2.5字符串的操作 - 大小写转换
代码说明
string.capitalize()把字符串的第一个字符大写
string.title()把字符串的每个单词首字母大写
string.lower()转换 string 中所有大写字符为小写
string.upper()转换 string 中的小写字母为大写
string.swapcase()翻转 string 中的大小写
# captalize,swapcase,title

name = 'yuluo123'
print(name.capitalize())   # Yuluo123        首字母大写
print(name.swapcase())     # YULUO123        大小写翻转

msg = 'yuluo say hi'
print(msg.title())         # Yuluo Say Hi    每个单词的首字母大写

3.2.2.6 字符串操作 - 文本对齐
代码说明
string.ljust(width)返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
string.rjust(width)返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
string.center(width)返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
# 内同居中,总长度,空白处填充

a = 'yuluo'
ret = a.center(20,"*")    # 长度为20,不足之处用'*'居中补齐
print(ret)

# 输出结果:
*******yuluo********

3.2.2.7 字符串操作 - 去除空白字符
代码说明
string.lstrip()截掉 string 左边(开始)的空白字符
string.rstrip()截掉 string 右边(末尾)的空白字符
string.strip()截掉 string 左右两边的空白字符
# strip 脱去指定字符

name='*barry**'
print(name.strip('*'))    # barry    两边脱去'*'字符
print(name.lstrip('*'))   # barry**  左边脱去'*'字符
print(name.rstrip('*'))   # *barry   右边脱去'*'字符

3.2.2.8 字符串操作 - 分割字符串
# split 分割,最终形成一个列表此列表不含有这个分割的元素。

ret1 = 'title,Tilte,atre,'.split('t')      # 以't'进行分割
print(ret1)                                # ['', 'i', 'le,Til', 'e,a', 're,']

ret2 = 'title,Tilte,atre,'.rsplit('t',1)   # 从右以't'开始分割,次数为1次
print(ret2)                                # ['title,Tilte,a', 're,']

3.2.2.9 字符串操作 - 格式化输出
# format的三种玩法 格式化输出

# 根据默认位置进行传入
res1='{} {} {}'.format('yuluo',18,'male')
print(res1)       # 输出结果:yuluo 18 male


# 根据索引进行传入
res2='{1} {0} {1}'.format('yuluo',18,'male')
print(res2)       # 输出结果:18 yuluo 18


# 根据关键字进行传入
res3='{name} {age} {sex}'.format(sex='male',name='yuluo',age=18)
print(res3)       # 输出结果:yuluo 18 male

3.2.3 布尔类型(bool:True/False )

布尔类型很简单,就两个值 ,一个True(真),一个False(假),主要用于逻辑判断

  • 真 True   非 0 数 —— 非零即真

  • 假 False  0

现在有2个值 , a=3,b=5 , 我说a>b你说成立么? 我们当然知道不成立,但问题是计算机怎么去描述这成不成立呢?或者说a< b是成立,计算机怎么描述这是成立呢?没错,答案就是,用布尔类型

a = 3
b = 5

print(a > b)    # 不成立就是False,即假
# 输出结果:False

print(a < b)    # 成立就是True, 即真
# 输出结果:True

3.2.4 列表(list)

3.2.4.1 列表的认识
  • 大家都知道数字主要用于计算,bool值主要是条件判断,只有字符串可以用于数据的存储,这些数据类型够用么?对于一门语言来说,肯定是不够用的。就说字符串:

    • 字符串只能存储少量的数据,对于大量的数据用字符串操作不方便也不易存储

    • 字符串存储的数据类型太单一,只能是字符串类型

  • 例如:‘1 True yuluo’ 像这样的字符串,我如果通过切片或者其他方法将1 True yuluo 取出来,他也只能是字符串,但是我想要得到数字的1,布尔值的True,必须还要转化,是不是很麻烦?所以Python给咱们也提供了一类数据类型,他能承载多种数据类型,这类数据类型被称作容器类数据类型可以存储大量的数据。列表就属于容器类的数据类型

  • 列表是Python中的基础数据类型之一,其他语言中也有类似于列表的数据类型,比如js中叫数组,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如:

    li = [ ‘yuluo’, 123, Ture, (1,2,3,’yuluo’), [1,2,3,’yuluo’,], {‘name’:’yuluo’} ]

  • 列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据,而且列表是有序的,有索引值,可切片,方便取值

3.2.4.2 列表的创建

创建一个列表有三种方式:

# 方式一:(常用)
l1 = [1, 2, '雨落']

# 方式二:(不常用)
l1 = list(iterable)            # l1 = list('可迭代对象') 
l1 = list('123')               # '123'被当做3个元素传入
print(l1)                      # 输出结果:['1', '2', '3']

# 方式三:列表推导式
l1 = [i for i in range(1,5)]
print(l1)                      # 输出结果:[1, 2, 3, 4]

3.2.4.3 列表的索引和切片

用法基本同字符串

l1 = ['a', 'b', '雨落', 3, 666]

# 列表的索引
print(l1[0])      # 'a'
print(l1[-1])     # 666

# 列表的切片
print(l1[1:3])    # ['b', '雨落']
print(l1[:-1])    # ['a', 'b', '雨落', 3]

# 列表带步长的切片
print(l1[::2])    # ['a', '雨落', 666]
print(l1[::-1])   # [666, 3, '雨落', 'b', 'a']

练习1:

li = [1, 3, 2, "a", 4, "b", 5,"c"]
# 通过对li列表的切片形成新的列表l1,l1 = [1,3,2]
print(li[:3])

# 通过对li列表的切片形成新的列表l2,l2 = ["a",4,"b"]
print(li[3:6])

# 通过对li列表的切片形成新的列表l4,l4 = [3,"a","b"]
print(li[1:6:2])

# 通过对li列表的切片形成新的列表l6,l6 = ["b","a",3]
print(li[-3:-8:-2])

3.2.4.4 列表的增删改查
3.2.4.4.1 列表的增

主要有三个:append、insert、extend

1、append 追加:给列表的最后面追加一个元素

l = [1, 2, 'a']
l.append(666)    # 在原列表尾部增加'666'
print(l) 

# 输出结果:
[1, 2, 'a', 666]

2、insert 插入:在列表的任意位置插入元素

l = [1, 2, 'a']
l.insert(1,'雨落')    # 在原列表序列为1的位置插入'雨落'
print(l) 

# 输出结果:
[1, '雨落', 2, 'a']

3、extend 迭代着追加,在列表的最后面迭代着追加一组数据

l = [1, 2, 'a']
l.extend('雨落a')    # 在原列表尾部迭代添加元素
print(l)

# 输出结果:
[1, 2, 'a', '雨', '落', 'a']

3.2.4.4.2 列表的删

主要有pop、remove、clear、del、切片删除

1、pop 通过索引删除列表中对应的元素,该方法有返回值,返回值为删除的元素

l = ['雨落', 'yuluo', 'qingyan', '庆言']
ret = l.pop(1)    # 删除列表索引为1的元素
print(ret,l) 

# 输出结果:
yuluo ['雨落', 'qingyan', '庆言']

2、remove 通过元素删除列表中该元素

l = ['雨落', 'yuluo', 'qingyan', '庆言']
l.remove('yuluo')    # 删除列表元素为'yuluo'的元素
print(l)

# 输出结果:
['雨落', 'qingyan', '庆言']

3、clear 清空列表

l = ['雨落', 'yuluo', 'qingyan', '庆言']
l.clear()    # 原列表将被清空
print(l)

# 输出结果:
[]

4、del 按照索引删除该元素

l = ['雨落', 'yuluo', 'qingyan', '庆言']
del l[2]    # 删除索引为2的元素
print(l)

# 输出结果:
['雨落', 'yuluo', '庆言']

5、切片删除该元素

l = ['雨落', 'yuluo', 'qingyan', '庆言']
del l[1:]    # 删除索引从1开始后的所有元素
print(l)

# 输出结果:
['雨落']

6、切片(步长)删除该元素

l = ['雨落', 'yuluo', 'qingyan', '庆言']
del l[::2]    # 删除原列表从索引为0开始,步长为2的元素
print(l)

# 输出结果:
['yuluo', '庆言']

3.2.4.4.3 列表的改

主要是按照索引和切片进行修改

1、按照索引改值

l = ['雨落', 'yuluo', 'qingyan', '庆言']
l[0] = '男神'    # 将列表索引为0的元素做修改
print(l)

# 输出结果:
['男神', 'yuluo', 'qingyan', '庆言']

2、按照切片改值(迭代着增加)

l = ['雨落', 'yuluo', 'qingyan', '庆言']
l[1:3] = 'abcd'    # 将原列表索引为1-3的元素用'a''b''c''d'代替
print(l)

# 输出结果:
['雨落', 'a', 'b', 'c', 'd', '庆言']

3、按照切片(步长)改值(必须一一对应)

l = ['雨落', 'yuluo', 'qingyan', '庆言']
l[::2] = '对应'    # 将原列表索引从0开始,步长为2 依次替换
print(l)

# 输出结果:
['对', 'yuluo', '应', '庆言']

3.2.4.4.4 列表的查

主要是按照切片或者循环去查看

1、切片:string[X:X:X]

2、循环:for i in list:……

3.2.4.5 列表的其他操作

1、count 计数:方法统计某个元素在列表中出现的次数

a = ["q","w","q","r","t","y"]
print(a.count("q"))

# 输出结果:
2

2、index 索引:方法用于从列表中找出某个值第一个匹配项的索引位置

a = ["q","w","r","t","y"]
print(a.index("r"))

# 输出结果:
2

3、sort 升序:方法用于在原位置对列表进行排序

a = [2,1,3,4,5]

a.sort()          # 修改原列表,自身没有返回值
print(a.sort())   # None  修改原列表,自身没有返回值
print(a)          

# 输出结果:
[1, 2, 3, 4, 5]

4、reverse 翻转:方法将列表中的元素反向存放

a = [2,1,3,4,5]

a.reverse()           # 修改原列表,自身没有返回值
print(a.reverse() )   # None   修改原列表,自身没有返回值
print(a)              

# 输出结果:
[5, 4, 3, 1, 2]

5、列表也可以相加与整数相乘

l1 = [1, 2, 3]
l2 = [4, 5, 6]
print(l1 + l2)  
print(l1 * 3)
​
# 输出结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 1, 2, 3, 1, 2, 3]

练习,对于列表 l1 = ["雨落", "YL", "庆言", "QY"]

1. 计算列表的长度并输出

print(len(l1))

# 输出结果:
4

2. 列表中追加元素"女神",并输出添加后的列表

l1.append('女神')
print(l1)

# 输出结果:
['雨落', 'YL', '庆言', 'QY', '女神']

3. 请在列表的第1个位置插入元素"帅哥",并输出添加后的列表

l1.insert(0,'帅哥')
print(l1)

# 输出结果:
['帅哥', '雨落', 'YL', '庆言', 'QY']

4. 请修改列表第2个位置的元素为"帅哥",并输出修改后的列表

l1[1] = '帅哥'
print(l1)

# 输出结果:
['雨落', '帅哥', '庆言', 'QY']

5. 请将列表l2=[1,"a"]的每一个元素添加到列表l1中,一行代码实现,不允许循环添加

l2=[1,"a"]
print(l1 + l2)

# 输出结果:
['雨落', 'YL', '庆言', 'QY', 1, 'a']

6. 请将字符串s = "NB"的每一个元素添加到列表l1中,一行代码实现,不允许循环添加

s = "NB"
print(l1 + list(s))

# 输出结果:
['雨落', 'YL', '庆言', 'QY', 'N', 'B']

7. 请删除列表中的元素"YL",并输出添加后的列表

l1.remove('YL')
print(l1)

# 输出结果:
['雨落', '庆言', 'QY']

8. 请删除列表中的第2个元素,并输出删除的元素和删除元素后的列表

print(l1.pop(1))
print(l1)

# 输出结果:
YL
['雨落', '庆言', 'QY']

9. 请删除列表中的第2至4个元素,并输出删除元素后的列表

del l1[1:4]
print(l1)

# 输出结果:
['雨落']

3.2.5 元祖(tuple)

3.2.5.1 元祖的认识
  • 对于容器型数据类型list,无论谁都可以对其增删改查,那么有一些重要的数据放在list中是不安全的,所以需要一种容器类的数据类型存放重要的数据,创建之初只能查看而不能增删改,这种数据类型就是元组

  • 元组:俗称不可变的列表,又被成为只读列表,元祖也是Python的基本数据类型之一,用小括号括起来,里面可以放任何数据类型的数据,查询可以,循环也可以,切片也可以,但就是不能改

  • 元组有一个特性,元组中如果只含有一个元素且没有逗号,则该元组不是元组,与改元素数据类型一致,如果有逗号,那么它是元组

tu = (1)                # 整数
print(tu,type(tu))      # 1 <class 'int'>

tu1 = ('yuluo')         # 字符串
print(tu1,type(tu1))    # yuluo <class 'str'>

tu2 = ([1, 2, 3])       # 列表
print(tu2,type(tu2))    # [1, 2, 3] <class 'list'>


'''------一旦加上逗号,就会变成元组------'''

tu = (1,)
print(tu,type(tu))      # (1,) <class 'tuple'>

tu1 = ('yuluo',)
print(tu1,type(tu1))    # ('yuluo',) <class 'tuple'>

tu2 = ([1, 2, 3],)
print(tu2,type(tu2))    # ([1, 2, 3],) <class 'tuple'>

3.2.5.2 元祖的索引和切片

数据类型的索引和切片操作基本都一致

tu = ('a', 'b', '雨落', 3, 666)

# 元组的索引
print(tu[0])       # 'a'
print(tu[-1])      # 666

# 元组的切片
print(tu[1:3])     # ('b', '雨落')
print(tu[:-1])     # ('a', 'b', '雨落', 3)

# 元组的带步长的切片
print(tu[::2])     # ('a', '雨落', 666)
print(tu[::-1])    # (666, 3, '雨落', 'b', 'a')

3.2.5.3 元祖的其他操作

因为元组的特性,直接从属于元组的元素不能更改,所以元组只能查看

1、len:获取元组元素个数

tu = ('雨落', '雨落', '庆言', 'QY', [1, 2, 3])
print(len(tu))

# 输出结果:
5

2、count:获取某元素在列表中出现的次数

tu = ('雨落', '雨落', '庆言', 'QY', [1, 2, 3])
print(tu.count('雨落'))

# 输出结果:
2

3、index:通过元素找索引(可切片),找到第一个元素就返回,找不到该元素即报错

tu = ('雨落', '雨落', '庆言', 'QY', [1, 2, 3])
print(tu.index('雨落'))

# 输出结果:
0

4、for 循环:查看元素

tu = ('雨落', '雨落', '庆言', 'QY', [1, 2, 3])
for i in tu:
    print(i)

# 输出结果:
雨落
雨落
庆言
QY
[1, 2, 3]

3.2.6 字典(dict)

3.2.6.1 字典的认识
  • 咱们目前已经学习到的容器型数据类型只有list,那么list够用?他有什么缺点呢?

    • 列表可以存储大量的数据类型,但是如果数据量大的话,他的查询速度比较慢

    • 列表只能按照顺序存储,数据与数据之间关联性不强

    所以针对于上的缺点,说咱们需要引入另一种容器型的数据类型,解决上面的问题,这就需要dict字典

  • 数据类型可以按照不同的角度进行分类,先给大家按照可变与不可变的数据类型的分类:

数据分类(hash)数据类型
可变数据类型(不可哈希)list,dict,set
不可变数据类型(可哈希)int,str,bool,tuple
  • 字典是Python语言中的映射类型,他是以{}括起来,里面的内容是以键值对的形式储存的:

    Key: 不可变的数据类型,并且键是唯一的,不重复的

    Value:任意数据(int,str,bool,tuple,list,dict,set),包括后面要学的实例对象等

  • 在Python3.6版本之后,字典会按照初建字典时的顺序排列(即第一次插入数据的顺序排序)

  • 当然,字典也有缺点:就是内存消耗巨大

3.2.6.2 字典的创建

1、方式一

dic1 = dict((('one', 1),('two', 2),('three', 3)))
dic2 = dict([('one', 1),('two', 2),('three', 3)])
print(dic1,dic2)  

# 输出结果:
{'one': 1, 'two': 2, 'three': 3}
{'one': 1, 'two': 2, 'three': 3}

2、方式二

dic = dict(one=1, two=2, three=3)
print(dic)  

# 输出结果:
{'one': 1, 'two': 2, 'three': 3}

3、方式三

dic = dict({'one': 1, 'two': 2, 'three': 3})
print(dic) 

# 输出结果:
{'one': 1, 'two': 2, 'three': 3}

4、方式四:zip

dic = dict(zip(['one', 'two', 'three'],[1, 2, 3]))
print(dic)

# 输出结果:
{'one': 1, 'two': 2, 'three': 3}

5、方式五

dic = { k: v for k,v in [('one', 1), ('two', 2), ('three', 3)]}
print(dic)

# 输出结果:
{'one': 1, 'two': 2, 'three': 3}

6、方式六:fromkeys - 以序列中的元素做字典的键,值为字典所有键对应的初始值

dic = dict.fromkeys('abc', '雨落')
print(dic)  

# 输出结果:
{'a': '雨落', 'b': '雨落', 'c': '雨落'}
dic = dict.fromkeys([1, 2, 3],'雨落')
print(dic)

# 输出结果:
{1: '雨落', 2: '雨落', 3: '雨落'}

这里有个坑,如果通过fromkeys得到的字典的值为可变的数据类:

dic = dict.fromkeys([1, 2, 3], [])
dic[1].append(666)     # 值是可变数据类型,若修改则值做统一修改

print(dic)             # 字典的值都一样,包括下面的id[值]
print(id(dic[1]),id(dic[2]),id(dic[3]))

# 输出结果:
{1: [666], 2: [666], 3: [666]}
1981866730944 1981866730944 1981866730944

3.2.6.3 验证字典的合法性

键的设立一定是不可变得数据类型,而值可以是任意数据

  • 如下是合法的
dic = {123: 456, True: 999, "id": 1, "name": 'yuluo',
       "age": 18, "stu": ['帅哥', '美⼥'], (1, 2, 3): '雨落'}

print(dic[123])            # 456
print(dic[True])           # 999
print(dic['id'])           # 1
print(dic['stu'])          # ['帅哥', '美⼥']
print(dic[(1, 2, 3)])      # 雨落

  • 如下是不合法的
dic = {[1, 2, 3]: '啊啊啊'}          # list是可变的. 不能作为key
dic = {{1: 2}: "哈哈哈"}             # dict是可变的. 不能作为key
dic = {{1, 2, 3}: '呵呵呵'}          # set是可变的, 不能作为key

3.2.6.4 字典的增删改查
3.2.6.4.1 字典的增

1、通过键值对:没有则添加,存在则修改

dic = {'name': '庆言', 'age': 18}

dic['weight'] = 50        # 没有weight这个键,就增加键值对
print(dic)                # {'name': '庆言', 'age': 18, 'weight': 50}

dic['name'] = 'qingyan'   # 有name这个键,就成了字典的改值
print(dic)                # {'name': 'qingyan', 'age': 18, 'weight': 50}

2、setdefault:没有则添加,存在则不变,且存在返回值

dic = {'name': '庆言', 'age': 18}

dic.setdefault('height',165)        # 没有height此键,则添加
print(dic)                          # {'name': '庆言', 'age': 18, 'height': 165}

dic.setdefault('name','qingyan')    # 有此键则不变
print(dic)                          # {'name': '庆言', 'age': 18, 'height': 165}

dic = {'name': '庆言', 'age': 18}
ret = dic.setdefault('name')        # 它有返回值
print(ret)                          # 庆言

3、update:没有则添加,存在则修改

dic = {'name': '庆言', 'age': 18}

dic.update([(1, 'a'),(2, 'b')])
print(dic)   

# 输出结果:
{'name': '庆言', 'age': 18, 1: 'a', 2: 'b'}

3.2.6.4.2 字典的删

1、pop:通过key删除字典的键值对,有返回值,可设置返回值

dic = {'name': '庆言', 'age': 18}

ret = dic.pop('name')           # '庆言'就是按照'name'删除后的返回值
print(ret)                      # 庆言     
print(dic)                      # {'age': 18}

ret1 = dic.pop('n',None)        # 未找到'n'这个键,故不删除,返回值为None
print(ret1)                     # None
print(dic)                      # {'age': 18}

2、popitem:随机删除,3.6版本之后为删除最后一个,有返回值(元组形式)

dic = {'name': '庆言', 'age': 18}

ret = dic.popitem()     # 默认删除最后一对,所以返回值是('age', 18)
print(ret)              # ('age', 18)
print(dic)              # {'name': '庆言'}

3、clear:清空字典

dic = {'name': '庆言', 'age': 18}

dic.clear()
print(dic)           # {}

4、del:可按照键删除键值对,也可以删除整个字典

dic = {'name': '庆言', 'age': 18}
del dic['name']                      # 通过键删除键值对
print(dic)                           # {'age': 18}

del dic                              # 删除整个字典,则内存中不再存在
print(dic)                           # 报错  因为dic在内存中已经不存在了

3.2.6.4.3 字典的改

1、通过键值对直接改

dic = {'name': '庆言', 'age': 18}

dic['name'] = 'qingyan'
print(dic)

# 输出结果:
{'name': 'qingyan', 'age': 18}

2、update:更新

dic = {'name': '雨落', 'age': 18}

dic.update(sex='男', height=180)
print(dic)

# 输出结果:
{'name': '雨落', 'age': 18, 'sex': '男', 'height': 180}

还可以将A字典的数据更新到B字典里,如果B字典有则更新,没有则追加到尾部

dic1 = {"name":"雨落","age":18,"sex":"male"}
dic2 = {"name":"qingyan","weight":50}

dic1.update(dic2)    # 将dic2数据更新进dic1中去,若dic1中没有则追加至尾部
print(dic1)          
print(dic2)

# 输出结果:
{'name': 'qingyan', 'age': 18, 'sex': 'male', 'weight': 50}
{'name': 'qingyan', 'weight': 50}

3.2.6.4.4 字典的查

1、通过键查询:直接dic[key],若没有此键则会报错

dic = {'name': '庆言', 'age': 18}
print(dic['name'])                  # 庆言

2、get方法,没有此键会显示None

dic = {'name': '庆言', 'age': 18}
v = dic.get('name')
print(v)                           # 庆言

v = dic.get('name1')               # 没有此键,默认报"None"
print(v)                           # None

v = dic.get('name2', '没有此键')    # 此处设置了返回值为"没有此键"
print(v)                           # 没有此键

3、keys():取得字典中所有的键

dic = {'name': '庆言', 'age': 18}
print(dic.keys())                  # dict_keys(['name', 'age'])

4、values():取得字典中所有的值

dic = {'name': '庆言', 'age': 18}
print(dic.values())                # dict_values(['庆言', 18])

5、items():取得字典中所有的键值对

dic = {'name': '庆言', 'age': 18}
print(dic.items())                # dict_items([('name', '庆言'), ('age', 18)])

 3.2.6.5 字典的嵌套
dic = {
    'name':'雨落',
    'age':18,
    'music':[{'music1':'姬霓太美','music2':'律师函警告'}],
    'hobby':{'hobby1':'唱跳','hobby2':'rap','hobby3':'篮球'}
}

1、取到“雨落”这个姓名

print(dic['name'])


# 输出结果:
雨落

2、取到音乐这个字典

# 方式一:
music_dic = dic['music']
print(music_dic[0])

# 方式二:
print(dic['music'][0])


# 输出结果:
{'music1': '姬霓太美', 'music2': '律师函警告'}

3、取到“律师函警告”这个音乐名

# 方式一:
music_dic = dic['music']
music = music_dic[0]
print(music['music2'])

# 方式二:
print(dic['music'][0]['music2'])


# 输出结果:
律师函警告

4、取到“篮球”这个爱好

# 方式一:
hobby_dic = dic['hobby']
hobby = hobby_dic['hobby3']
print(hobby)

# 方式二:
print(dic['hobby']['hobby3'])


# 输出结果:
篮球

3.2.6.6 字典的拆包
a,b = {'name': '庆言', 'age': 18}
print(a,b)

# 输出结果:
name age

同样也适用于列表、元组等

a,b = 1,2
print(a,b)    # 1 2


a,b = ['庆言',18]
print(a,b)    # 庆言 18


a,b = ('庆言',18)
print(a,b)    # 庆言 18

3.2.6.7 字典的其他操作
dic = {'name': '庆言', 'age': 18}

1、将该字典的键和值分别打印出来

key_list = dic.keys()
value_list = dic.values()

# 可以分别打印出键和值

print(key_list)      # dict_keys(['name', 'age'])
print(value_list)    # dict_values(['庆言', 18])

2、将上方打印的高仿列表转化为真正的列表

# 也可以转换成真正的列表

print(list(key_list))      # ['name', 'age']
print(list(value_list))    # ['庆言', 18]

3、循环打印键和值

# 循环打印键:

for k in dic:
    print(k)

# 输出结果:
name
age


#循环打印值:

for v in dic.values():
    print(v)

# 输出结果:
庆言
18

4、加以拆包的知识点

for k,v in dic.items():
    print('键:',k)
    print('值:',v)

# 输出结果:
键: name
值: 庆言
键: age
值: 18

3.2.7 集合(set)

3.2.7.1 集合的认识

集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。以下是集合最重要的两点:

  • 去重,把一个列表变成集合,就自动去重了

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

  • 空集合表示为:set()

3.2.7.2 集合的创建

直接生成或者用set()方法

set1 = {1,2,'庆言'}
set2 = set({1,2,'庆言'})

print(set1,set2)          # {1, 2, '庆言'}  {1, 2, '庆言'}

3.2.7.3 集合的增删
3.2.7.3.1 集合的增

1、方式一:add

set1 = {'雨落','庆言','yuluo'}
set1.add('qingyan')

print(set1)

# 输出结果:
{'qingyan', '庆言', 'yuluo', '雨落'}

2、方式二:update 迭代着增加

set1 = {'雨落','庆言','yuluo'}

set1.update('A')
print(set1)

set1.update('B')
print(set1)

set1.update([1,2,3])
print(set1)

# 输出结果:
{'A', '庆言', '雨落', 'yuluo'}
{'A', 'yuluo', '雨落', 'B', '庆言'}
{1, 2, 3, 'A', 'yuluo', '雨落', 'B', '庆言'}

3.2.7.3.2 集合的删

1、remove:删除一个元素

set1 = {'雨落','庆言','yuluo'}

set1.remove('yuluo')
print(set1)

# 输出结果:
{'庆言', '雨落'}

2、pop:随机删除一个元素

set1 = {'雨落','庆言','yuluo'}

set1.pop()
print(set1)

# 输出结果:
{'庆言', '雨落'}

3、clear:清空集合

set1 = {'雨落','庆言','yuluo'}

set1.clear()
print(set1)

# 输出结果:
set()

4、del:删除集合

set1 = {'雨落','庆言','yuluo'}

del set1
print(set1)

# 输出结果:报错 因为set1集合已从内存中删除

3.2.7.4 集合的其他操作
3.2.7.4.1 交集

& 或者 intersection :两者共有的部分

set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}

print(set1 & set2)               # {4, 5}
print(set1.intersection(set2))   # {4, 5}

3.2.7.4.2 并集

| 或者 union :两者加一起所拥有的部分

set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}

print(set1 | set2)         # {1, 2, 3, 4, 5, 6, 7,8}
print(set2.union(set1))    # {1, 2, 3, 4, 5, 6, 7,8}

3.2.7.4.3 差集

- 或者 difference :前者比后者多拥有的部分

set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}

print(set1 - set2)             # {1, 2, 3}
print(set1.difference(set2))   # {1, 2, 3}

3.2.7.4.4 反交集

^ 或者 symmetric_difference :两者除了共有之外加一起所拥有的部分

set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}

print(set1 ^ set2)                       # {1, 2, 3, 6, 7, 8}
print(set1.symmetric_difference(set2))   # {1, 2, 3, 6, 7, 8}

3.2.7.4.5 子集与超集
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}

# 若下面两种情况为True,则说明set1是set2子集
print(set1 < set2)             # True
print(set1.issubset(set2))     # True

# 若下面两种情况为True,则说明set2是set1超集
print(set2 > set1)             # True
print(set2.issuperset(set1))   # True

3.2.7.4.6 冻结集合frozenset

让集合变成不可变类型

s = frozenset('yuluo')
print(s)
print(type(s))

# 输出结果:
frozenset({'y', 'o', 'l', 'u'})
<class 'frozenset'>

3.3 数据类型转换

3.3.1 int、str、bool

1、int → bool

i = 100
print(bool(i))   # True    非零即True
i1 = 0
print(bool(i1))  # False   零即False

2、bool -→ int

t = True
print(int(t))    # 1   True --> 1
t = False
print(int(t))    # 0   False --> 0

3、int → str

i1 = 100
print(str(i1))   # '100'

4、str → int:全部由数字组成的字符串才可以转化成数字

s1 = '90'
print(int(s1))   # 90

5、str → bool

s1 = '雨落'
s2 = ''
print(bool(s1))    # True 非空即True
print(bool(s2))    # False

6、bool → str

t1 = True
print(str(True))   # 'True'

3.3.2 str、list

1、str → list

s1 = 'yuluo 雨落'
print(s1.split())              # ['yuluo', '雨落']

2、list → str:前提 list 里面所有的元素必须是字符串类型

l1 = ['yuluo', '雨落']
print(' '.join(l1))            # 'yuluo 雨落'

3.3.3 list、set

1、list → set

s1 = [1, 2, 3]
print(set(s1))          # {1, 2, 3}

2、set → list

set1 = {1, 2, 3, 3,}
print(list(set1))       # [1, 2, 3]

3.3.4 str、bytes

1、str → bytes

s1 = '庆言'
print(s1.encode('utf-8'))          # b'\xe5\xba\x86\xe8\xa8\x80'

2、bytes → str

b = b'\xe5\xba\x86\xe8\xa8\x80'
print(b.decode('utf-8'))          # '庆言'

3.3.5 bool

除了以下可以转为False的,其他的数据类型都可以转为True

' ' 空字符串
0数字0
()空元组
{}空字典,注意与空集合的区别
[]空列表
set()空集合
None元素None

3.4 基础数据类型的总结

1、俺存储空间的占用-从低到高

① 数字
② 字符串
③ 集合: 无序,即无序存索引相关信息
④ 元组: 有序,需要存索引相关信息,不可变
⑤ 列表: 有序,需要存索引相关信息,可变,需要处理数据的增删改
⑥ 字典: 有序,需要存key与value映射的相关信息,可变,需要处理数据的增删改

2、按存值个数区分

  • 标量/原子类型:数字,字符串
  • 容器类型:           列表,元组,字典

3、按可变/不可变区分

  • 可变:   列表,字典
  • 不可变:数字,字符串,元组,布尔值

4、俺访问顺序区分

  • 直接访问:                        数字
  • 顺序访问(序列类型):   字符串,列表,元组
  • key值访问(映射类型): 字典
  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值